@

7.定义类

7.1 C#中的类定义

(关键词Class)默认情况下是只能当前项目可以访问

(internal)	class MyClass()
{
// Class mumber.
}

类的继承:

class ClassSon : MyClass
{
// class mumbers.
}

派生类的可访问性需低于基类

可以给一个类添加一个基类多个接口,(可以同时实现基类和接口的添加)但要注意,需先添加基类,再添加接口,之间用逗号连接。

public class MyClass : MyBase , IMyInterface
{
// Class mumbers.
}

7.1.1 接口的定义

(interface 关键字)

interface IMyInterface
{
// Interface mumbers.
}

修饰符用法一致,但是不能使用关键字 abstract 和 sealed(无意义)

7.1.2 修饰符

internal  //在本项目中公开(默认)
public //完全公开
abstract或 internal abstract //类只能在当前项目中访问,不能实例化,只能被继承
public abstract //类可以在任意位置访问,不能实例化,只能被继承
sealed 或 internal sealed //类只能在当前项目中访问,不能被继承,只能实例化
public sealed // 类可以是任意位置被访问,不能被继承,只能实例化

7.2 System.Object

.NET Framework 必须支持的基本方法:

Object()
~Object()
Equals(object)
Equals(object, object)
RefereceEquals(object, object)
Tostring()
MemberwiseClone()
GetType()
GetHashCode()

7.3 构造函数和析构函数

构造函数

class Myclass()
{
public MyClass()
{
// Constructor code
}
}

构析函数

class MyClass
{
~MyClass()
{
// Destructor body.
}
}

当进行垃圾回收时,就执行析构函数中的代码,释放资源

一般情况下,实例化时,先执行System.Object.Object(),之后执行这个类的基类构造函数,最后才执行该类的构造函数。

可以通过关键字base指定基类构造函数,如:

public class MyBaseClass
{
public MyBaseClass()
{
}
public MyBaseClass(int i)
{
}
} public class MyDerivedClass : MyBaseClass
{
// base 后面可以是常量,也可以是变量
public MyDerivedClass() : base(5)
{
}
public MyDerivedClass(int i)
{
}
public MyDerivedClass(int i, int j)
{
}
}

若调用默认构造函数,则执行顺序为:

  • 执行System.Object.Object()构造函数。
  • 执行MyBaseClass.MyBaseClass(int i)构造函数。
  • 执行MyDerivedClass.MyDerivedClass()构造函数。

也可以使用关键字this改变该类构造函数的执行顺序:

public class MyDerivedClass : MyBaseClass

{

	public MyDerivedClass() : this(5, 6)

	{

	}

	……

	public MyDerivedClass(int i, int j) : base(i)

	{

	}

}

如果使用MyDerivedClass()构造函数,执行顺序如下:

  • 执行System.Object.Object()构造函数。
  • 执行MyBaseClass.MyBaseClass(int i)构造函数。
  • 执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。
  • 执行MyDerivedClass.MyDerivedClass()构造函数。

即使用base的构造函数调用时,首先会执行另一个构造函数,使用注意不要创建无限循环

7.4 结构类型

(关键字struct)

定义与使用方法和类相似

区别:

类是引用,结构是值类型。即在类之间的变量赋值是指向同一位置,一个变量发生改变,其他的随之改变,而结构的变量则不会牵一发而动全身

7.5 浅度和深度复制

浅度赋值:复制引用

深度复制:复制全部信息

8.定义类成员

public     成员可以由任意代码访问
private 成员只能由类中代码访问(默认)
internal 成员只能由项目内部代码访问
protected 成员只能由家族(类或派生类)中的代码访问
static 静态成员,只能通过定义他们的类来访问

8.1 定义类成员

  • 字段
class MyClass
{
// .NET Framework中公共字段以PascalCasing方式命名
public int MyInt;
}

也可通过关键字readonly修饰,表示字段只能在初始化的时候赋值(执行构造函数时)

class MyClass
{
public readonly int MyInt = 13;
}

const 成员也是静态的不需要static修饰

  • 方法
	class MyClass
{
public string GetString( ) => return "here is a GaoYao."
}
virtual   方法可以重写

abstract  方法必须在非抽象类中重写(只能用于抽象类)

override  方法重写了一个基类方法(如果方法被重写,就必须使用该关键字)

extern    方法定义放在其他地方

如果使用了override,也可以使用sealed进行再修饰,即这个方法不能由派生类重写

public class MyDerivedClass : MyClass
{
public override sealed void DoSomething()
{
// Dervied class implementation, overrides base implementation.
}
}
  • 属性
// 注意属性的命名方式

public int MyIntProp
{
get
{
// Property get code.
}
set
{
// Property set code.
}
}

get块必须有一个属性返回值,关键字value表示用户提供的属性值(不必考虑类型转换)

public int MyIntProp
{
get {return myInt; }
set
{
if( value >= 0 && value <= 10)
myInt = value;
}
}

只有赋值在0~10之间才会修改myInt,如果使用了无效值,则有四种选择:

什么也不做(如上)

给字段赋默认值

继续执行,就像没有错误发生一样,但记录下该事件,已备将来分析

抛出异常

(一般推荐使用有两种情况)

属性也可使用关键字:virtual、override和abstract,但不能用于字段

  • 重构成员

    表示使用工具修改代码

    (右击类图中的某个成员)

    作用:自动添加字段的属性

  • 自动属性

    输入prop后按Tap键两次,就自动创建:

public int MyProperty {get; set;}

只有get存储的自动属性,和自动属性的初始化(无只写的自动属性)

public int MyIntProp {get; }
public int MyIntProp {get; } = 9;

8.2 类成员的其他主题

8.2.1 隐藏和重写基类方法

隐藏:派生类共享基类方法,因此调用时分不清楚。将基类方法隐藏,再在派生类中写一个“一模一样”的方法。

public class MyBaseClass
{
public void Dosomething()
{
// Base implemetation.
}
} public class MyDeviedClass : MyBaseClass
{
// 使用关键字new显示说明
new public void Dosomething()
{
// Derived class implemetation, hides base implemetation.
}
}

(不使用new编译器会有一个警告)

重写后基类失去功能

public calss MyBaseClass
{
public virtual void DoSomething() => WriteLine('Base imp");
} public class MyDervivedClass : MyBaseClass
{
public orrived void Dosomething() => WriteLine('Derived imp");
}

8.2.2 this和base

base和this可在类中使用

base:在派生类中,表示基类的方法

如之前的例子,则base.DoSomething()表示基类的方法(即使将基类方法隐藏,也可在派生类内部访问)

this:1、把当前实例传递给一个方法。

public void DoSomething()
{
MyTargetClass myObj = new MyTargetClass;
myObj.DoSomethingWith(this);
}

2、限定局部类型成员

public class MyClass
{
private int someData;
public int someData
{
get
{
return this.someData;
}
}
}

显而易见,someData是引用成员,而不是变量。

8.2.3 嵌套的类型定义

public class MyClass
{
public class MyNestedClass
{
public int NestedClassField;
}
}

在MyClass外部实例化MyNestedClass,必须限定名称

MyClass.MyNestedClass myObj = new MyClass.MyNestedClass();

该功能主要用于定义对于包含类来说是私有的类,命名空间中的其他类就不能访问。另一个功能是嵌套类可以访问包含类的私有和受保护成员(原理:嵌套类可以访问包含类的 私有和受包含成员)。

8.3 接口的实现

接口成员定义与类成员的重要区别:

  • 不允许使用访问修饰符(public、private、protected或internal),所有接口成员都是隐式共用的。
  • 接口成员不能包含代码体
  • 接口不能定义字段成员
  • 不能用关键字static、virtual、abstract或sealed来定义接口成员
  • 类型定义成员是禁止的

隐藏基接口中继承的成员,与隐藏类成员方式一样

定义属性时可以根据需求省略任意一个

interface IMyInterface
{
int MyInt { get; set;}
}

8.3.1 在类中实现接口

public interface IMyInterface
{
void DoSomething( );
void DoSomthingElse( );
} public class MyClass : IMyInterface
{
public void DoSomething( ) { };
public void DoSomethingElse( ) { };
}

必须包含该接口所有成员的代码;必须匹配指定的签名(包括匹配指定的get块和set);必须是公开的。

可使用关键字virtual或abstract实现接口成员,但不能使用static或const,还可以在基类上实现接口成员。

继承一个实现给定接口的基类,就意味着派生类隐式支持这个接口。

8.3.2 显式实现接口成员

使用接口名+点句符

public class MyClass : IMyInterface
{
//显式
void IMyInterface.DoSomething( ) { };
//隐式
public void DothingSomeElse( ) { };
}

8.3.3 其他属性存储器

定义接口的存储器是公共的,只能添加非公共的存储器:

public inteface IMyInterface
{
int MyIntProperty { get;}
} public class MyIntProperface : IMyInterface
{
public int MyIntProperty { get; protected set;}
}

8.4 部分类的定义

1、给代码分组(折叠)

#region

……

#endregion

2、部分类定义

可以将字段、属性、构造函数放在一个文件中,把方法放在另一个文件(就是obj\DeBug这样的文件)中。

语法:

public partial class MyClass  { ……}

部分类定义的接口可以应用整个类,即部分类的继承等价于整个类的继承

public partial class MyClass : IMyInterface1 { ……}
public partial class MyClass : IMyInterface2 { ……}
//等价于
public class MyClass : IMyInterface1,IMyInterface { ……}

8.5 部分方法的定义

部分方法定义在一部分类中定义,另一份类中实现,两部分类都需要关键字partial

public partial class MyClass
{
public void MyPartialMethod( );
} public partial class MyClass
{
public void MyPartialMethod( )
{
// Method impementation.
}
}

部分方法可以是静态的,但总是私有的,不能有返回值(如果有返回值,就可以作为表达式的一部分)。使用的任何参数不能是out,可以是ref。部分方法也不能使用virtual、abstract、override、new、sealed和extern修饰符。(可以使用“ =>输出字符”)

编译时,如果没有实现部分方法的代码,编译器就会删除这部分,不会影响性能。

9.集合、比较和转换

9.1 集合

集合功能大多是通过System.Collection名称空间的接口获得的

优点:定制的集合类可以是强类型化的(从集合中提取项时,不需要将其转化为正确的类型);提供专用的方法。

9.1.1 集合的基本操作

ArrayList <ListName> = new ArrayList();  //声明+定义:

.add(<elementName>);  //添加项

.AddRang(<elementName>);  //一次添加好几项

.RemoveAt(<elementIndex>);  //删除项

.Remove(<elementName>);  //删除项

.Length;  //元素个数

.ToString;  //元素名称

9.1.2 创建自己的强化集合

  • 定义集合

    CollectionBase类有接口IEnumberable、ICollection、IList,但主要的是IListClear()和RemoveAt()方法,以及ICollection的Count属性。

    CollectionBase提供的两个受保护属性:

    List可以通过IList接口访问项。

    InnerList用于存储项的ArrayList对象。

    (他们可以访问存储的对象本身)

//Animal类的派生类是Cow

public class Animals : CollectionBase
{
public void Add(Animal newAnimal)
{
List.Add(newAniaml);
}
public void Remove(Animal oldAnimal)
{
List.Remove(oldAnimal);
}
public Animal() { }
} //则可以这样调用:
Animals animalCollection = new Animals();
animalCollection.Add(new Cow ("lea"));
  • 索引符

    也可以通过索引调用(添加索引符):
public class Animals : CollectionBase
{
……
public Animal this(int animalIndex)
{
get { return (Animal)List(animalIndex); }
set { List[animalIndex] = value; }
}
} //访问时:
animalCollection[0].Tostring();
//而不是:
( (Animal)aniamlCollection).ToString();
  • 键控集合和IDictionary

    DictionaryBase和CollectionBase作用一样,但有如下区别:

    DictionaryBase不实现MoveAt()

    成员区别:

    Add()- 带两个参数:一个键和一个值,实现时使用string值作为键。

    Remove()- 以键为参数,指定键的相应项被删除

    foreach工作方式的区别

foreach (DictionaryEntry myEntry in animalCollection)

{

	WriteLine( $" New {myEntry.Value.Tostring()} object added to" + $"custom collection, Name = { (Animal)myEntry.Value}.Name");

}

9.1.3 迭代器

是一个代码块,按顺序提供了在foreach中使用的所有值

语法:yield return <value>

迭代一个类,使用方法GetEnumerator(),其返回值是IEnumerator

迭代一个类成员(例如一个方法),使用IEnumerable

public static IEnumerable SimpleList()
{
yield return "string 1";
yield return "string 2";
yield return "string 3";
}
static void Main(string[ ] args)
{
foreach(string item in SimpleList())
WriteLine(item);
ReadKey();
} //结果如下:
string 1
string 2
string 3

使用该语句中断将信息返回给foreach循环:yield break;

在后台,调用yield都会中断代码的执行,当请求一个值时,也就是使用foreach循环开始一个新循环时,代码会恢复执行

9.1.4 深度赋值

public class Content
{
public int Val;
} public class clone
{
public Content MyContent = new Content();
public Cloner(int newVal)
{
MyContent.Val = newVal;
}
public object GetCopy() => MemberwiseClone();
} //会通过GetCopy得到一个浅度复制
Cloner mySource = new Cloner(5);
Cloner myTarget = (Cloner)myCloner.GetCopy();
WriteLine($"myTarget.MyCloner.Val = {myTarget.MyContent.Val}");
mySource.MyContent.Val = 2;
WriteLine($"myTarget.MyCloner.Val = {myTarget.MyContent.Val}"); //此时的输出结果为:
myTarget.MyCloner.Val = 5
myTarget.MyCloner.Val = 2 //如果要实现深度复制,需修改GetCopy方法,如下:
public class cloner : ICloneable
{
public Content MyContent = new Content();
public Cloner(int newVal)
{
MyContent.Val = newVal;
}
public object Clone()
{
Cloner clonedCloner = new Cloner(MyCloner.Val);
retrun clonedClonder;
}
}

继承ICloneable接口,其中有一个Clone方法,该方法无参数,有object返回值,使用时和GetCopy方法相同

在复杂的系统中,需要进行多次深度复制,调用Clone就是一个递归的过程(如下面这个两次复制)。

public class cloner : ICloneable
{
public Content MyContent = new Content();
……
public object Clone()
{
Cloner clonedCloner = new Cloner();
clonedCloner.MyContent = MyContent.Clone(); //递归
return clonedCloner;
}
}

9.2 比较

9.2.1 封箱和拆箱

封箱是隐式的,拆箱则需要显示转换。

封箱允许在项是object的时候使用值类型,内部机制允许在值类型上调object方法。

访问值类型内容前,必须先拆箱

9.2.2 值比较

  • 运算符重载
public class AddClass1
{
public int Val;
} AddClass1 op1 = new AddClass1();
op1.Val = 5;
AddClass1 op2 = new AddClass1();
op2.Val = 5;
bool op3 = op2==op3;

上面的代码可以运行,但不会达到预期的结果。比较的是op1和op2是否引用同一对象。

通过等于号重载实现预期的效果,只需要修改类:

public class AddClass1
{
public int Val;
public static bool operator ==(AddClass1 op1, AddClass op2)
{
return ( op1.Val == op2.Val )true : false;
}
}

与静态方法的声明类似,使用关键字operator。

可以重载的运算符:

一元 —— +,-,!,~,++,--,true,false

二元 —— +,-,*,/,%,^,|,<<,>>

比较运算符 —— ==,!==,<,>,<=,>=

有混合类型时,注意操作数的使用顺序。

  • 对集合排序

    默认比较方式的排序和非默认比较方式的排序

    如ArrayList包含的方法Sort。

  • IComparable接口和IComparer接口

    IComparable在要比较的类中实现,可以比较该对象和另一个对象

    IComparer在一个单独类中实现,可以比较任意两个对象

    IComparable提供了一个CompareTo方法:<object1>.CompareTo(<object2>)

    IComparer提供了Compare方法:Compare( <object1>, <obbject2>)

    两个方法的返回值均是int型。

    两种方法提供的参数均为System.Object,在返回结果之前,通常需要类型比较。

    对简单类型的比较:

Comparer.Default.Compare( <object1>, <object2>)

object1大则返回1,object2大则返回-1,一样大返回0。(这里通过Default获取类的实例)

Compare类的注意事项:

1、检查传送给Comparer.Compare( )的对象,看他们是否支持IComparable。如果支持就使用该代码

2、允许使用“null”,它表示小于其他任意对象

3、字符串根据当前文化处理。Comparer必须使用当前构造函数进行实例化以便传送用于指定所使用文化的System.Globalization.CultureInfo对象

4、字符串在处理时要区分大小写。不希望区分时,则需要使用CaseInsensitiveComparer类,该类以相同的方式工作

9.2.3 is

类型转换

<operand> is <type>

表达式结果如下:

  • 如果是一个类类型,也是该类型,或者它继承了该类型,或者它可以封箱到该类型中,结果为true
  • 如果是一个接口类型,也是该类型,或者它是实现该接口的类型,结果为true
  • 如果是一个值类型,也是该类型,或者它可以拆箱到该类型中,结果为true

9.3 转换

  • 重载类型转换符

    重载可以进行隐式、显示转换和不相关类型转换。
public class ConvClass1
{
public int Val;
/* 如果认为这部分可以省略,则说明之前的运算符重载部分没有理解,
建议在这里多看几遍*/
public static implicit operator ConvClass2(ConvClass op1)
{
ConvClass2 returnVal = new ConvClass2();
returnVal.Val = op1.Val;
return returnVal;
}
}
public class ConvClass2
{
public double Val;
public static explicit operator ConvClass1(ConvClass op1)
{
ConvClass1 returnVal = new ConvClass1();
checked{ returnVal.Val = (int)op1.Val;}
return returnVal;
}
} //调用
ConvClass1 op1 = new ConvClass();
op1.Val = 3;
ConvClass2 op2 = op1;
//但反向时会出现一个异常
ConvClass2 op1 = new ConvClass2();
op1.Val = 3e15;
ConvClass1 op2 = (ConvClass2)op1;

使用关键字implicit( 隐式 [默认])和explicit(显式)指定(显隐)转换,使用关键字checked,对整型运算和转换显示启用溢出检查

  • as运算符

    as运算符一般适用于引用类型转换
<operand> as <type>

只适用于:

<operand>的类型是<type>
<operand>可以隐式转换为<type>类型
<operand>可以封箱到<type>类型中
//如果转换失败,表达式结果为null
class ClassA : IMyInterface()
class ClassD : ClassA() //示例一,以下结果为:null
ClassA ob1 = new ClassA();
ClassD ob2 = ob1 as (ClassD); //示例二,以下代码没有异常
ClassD ob1 = new ClassD();
ClassA ob2 = ob1;
ClassD ob3 = ob2 as (ClassA); //示例三,抛出一个异常
ClassA ob1 = new ClassA();
ClassD ob2 = (ClassD)ob1;

10.泛型

10.1 使用泛型

10.1.1 可空类型

之前我们学习到:值类型只能是值,而引用类型可以是null。为解决某些问题,可以让值类型也使用null。

System.Nullable<int> nullableInt;  /* 声明了可空变量nullableInt*/
int? nullableInt; /* 这行代码是上面的缩写,而且更便于读取*/
if( nullableInt.HasVaule) { ……}
/* 可以使用HasValue属性,但引用类型无法做到*/
  • 运算符和可空类型

    可空类型可以使用自己提供的运算符
//result不是int?类型,所以不会编译
int? op1 = 5;
int result = op1 * 2;
//必须进行显式转换
int result = (int)op1 * 2;
//或通过Value属性访问值
int result = op1.Vaule * 2; //当运算表达式中有一个或两个是null时,其结果为null
int? op1 = null;
int? op2 = 5;
int? result = op1 * op2;

但是bool?除外,对于bool?,&和 | 的定义运算符都会得到符合逻辑的结果。

  • ??运算符

    空合并运算符
op1 ?? op2;   <=>
op1 == null ? op2 : op1;

优点:便捷(不需要if和三元运算符)

  • ?.运算符

    Elvis运算符或空条件运算符

    (避免繁杂的空值检查造成歧义)
int count = 0;
if (customer.orders != null)
{
count = customer.orders.Count();
}
//若客户没有订单(null),就会抛出异常
//使用?.运算符会把int? count设置为null
int?. count = customer.orders?.Count();
//也可以设置一个默认值
int? count = customer.orders?.Count ?? 0; //另一个用途是触发事件
var onChanged = OnChanged;
if ( onChanged != null)
{
onChanged(this, args);
}
/* 该模式不是线程安全的,因为有人会在null检查完成后,
退订最后一个事件处理程序,此时会抛出异常,程序崩溃。
使用空条件可以避免这种情况*/
OnChanged?.Invoke( this, args);

类的==运算符重载中,使用?.检查null,可以避免使用方法抛出异常:

public static bool operator==( Card card1, Card card2)
=> (card1.suit == card2.suit) && (card1.rank == card2.rank);

如果左边对象card1不为空,就检索右边对象,否则终止访问链,返回null

10.1.2 System.Collections.Generic命名空间

  • List<T>

    创建T类型对象集合代码:
List<T> myCollection = new List<T>();
//Item属性,允许进行类似于数组的访问
T itemAtIndex = myCollectionOfT[2];
Animals animalCollection = new Animals();
//用泛型集合实现
List<Aniaml> animalCollection = new List<Animal>();
/* Aniaml是之前添加的索引符,可以对照《集合、比较和转换》的章节*/
/*之前添加的索引符代码也可以用下面这行替换*/
public class Animala : List<Animal> { }

11.高级C#技术

转载请注明出处^_^

【游戏开发笔记】编程篇_C#面向对象 {下}的更多相关文章

  1. [置顶] mmog游戏开发之业务篇

    这周不是很忙,因为我们的游戏开发了近一年,由于公司的业务调整,在游戏开第二服的时候,老板果断的把项目停到了. 感觉超级的不爽啊.因为这个游戏项目像我的孩子一样和我一样成长,里边的大概的业务逻辑都是偶实 ...

  2. ONVIFclient搜索设备获取rtsp地址开发笔记(精华篇)

    概要:           眼下ONVIF协议家族设备已占领数字监控行业半壁江山以上.亲,作为开发人员的你还在犹豫是否了解下吗?本文介绍了ONVIFclient从设备搜索,鉴权,能力获取,媒体信息获取 ...

  3. ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)

    原文  http://blog.csdn.net/gubenpeiyuan/article/details/25618177   概要: 目前ONVIF协议家族设备已占据数字监控行业半壁江山以上,亲, ...

  4. 【视频开发】ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)

    转载地址:http://blog.csdn.net/gubenpeiyuan/article/details/25618177 概要:           目前ONVIF协议家族设备已占据数字监控行业 ...

  5. 【unity3d游戏开发之基础篇】unity3d射线的原理用法以及一个利用射线实现简单拾取的小例子

    原地址:http://www.cnblogs.com/xuling/archive/2013/03/04/2943154.html 最近开始研究U3D,它的强大就不多说了, 今天研究了研究射线相关东西 ...

  6. 【android】开发笔记---存储篇

    SQLite批量插入数据 当我们执行 db.execSQL("sql语句")的时候,系统进行了一次IO操作,当批量插入成千上万条时,就会消耗掉许多资源. 解决之道是通过事务,统一提 ...

  7. 【开发笔记】- 在Windows环境下后台启动redis

    1. 进入 DOS窗口 2. 在进入Redis的安装目录 3. 输入:redis-server --service-install redis.windows.conf --loglevel verb ...

  8. 《C++游戏开发》笔记十一 平滑动画:不再颤抖的小雪花

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9430645 作者:七十一雾央 新浪微博:http:/ ...

  9. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记(1) - 执行在不同CM内核下

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记(1)之执行在不同CM内核下. 文接上篇 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计&g ...

  10. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

随机推荐

  1. [C++基础入门] 2、数据类型

    文章目录 2 数据类型 2.1 整型 2.2 sizeof关键字 2.3 实型(浮点型) 2.4 字符型 2.5 转义字符 2.6 字符串型 2.7 布尔类型 bool 2.8 数据的输入 2 数据类 ...

  2. Java的构造方法和标准JavaBean

    构造方法 一.构造方法概述: 构造方法也叫做构造器,构造函数,平时叫做构造方法 二.构造方法的作用: 创建对象的时候,由虚拟机自动调用,给成员变量进行初始化(赋值) 三.构造方法的格式: public ...

  3. 2022-02-21:不含连续1的非负整数。 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数。 输入: n = 5 输出: 5 解释: 下面是带

    2022-02-21:不含连续1的非负整数. 给定一个正整数 n ,返回范围在 [0, n] 都非负整数中,其二进制表示不包含 连续的 1 的个数. 输入: n = 5 输出: 5 解释: 下面是带有 ...

  4. get()、get_or_create()、first()、last()、latest()、earliest()、in_bulk()

    get() 查询. get_or_create() 不存在时更新.存在时查询并返回. first() 获取第一笔. last() 获取最后一笔. 使用latest和earliest时需要在元数据(me ...

  5. APP中RN页面热更新流程-ReactNative源码分析

    平时使用WebStorm或VSCode对RN工程中的文件修改后,在键盘上按一下快捷cmd+s进行文件保存,此时当前调试的RN页面就会自动进行刷新,这是RN开发相比于原生开发一个很大的优点:热更新. 那 ...

  6. Windows 安装ActiveMq5.16.6

    Windows 安装ActiveMq5.16.6 前言 最近因为需要在项目中使用MQ,所以就想在我的老Windows机器上装个ActiveMq. 1. 下载安装 先到Activemq官网下载安装需要版 ...

  7. deepin系统更新谷歌浏览器chrome的方法

    deepin系统更新谷歌浏览器chrome的方法 1 为什么要更新谷歌浏览器谷歌浏览器更新频繁,隔一段时间不更新,打开浏览器时会自动弹出一个提示更新的窗口,有点烦,如果使用python自动处理程序时, ...

  8. 记一次618军演压测TPS上不去排查及优化

    本文内容主要介绍,618医药供应链质量组一次军演压测发现的问题及排查优化过程.旨在给大家借鉴参考. 背景 本次军演压测背景是,2B业务线及多个业务侧共同和B中台联合军演. 现象 当压测商品卡片接口的时 ...

  9. shell学习总结

    shell教程 第一个shell脚本 打开文本编辑器(可以使用 vi/vim 命令来创建文件), 新建一个文件 test.sh,扩展名为 sh(sh代表shell) #!/bin/bash echo ...

  10. CF1832F Zombies

    简要题意 给定 \(n\) 个左闭右开的区间 \(A_i = [L_i, R_i)\),其中 \(0\le L_i < R_i \le x\),你可以自由选择 \(k\) 个长度为 \(m\) ...