继承和多态
2016-03-07 21:53
267 查看
1.虽然构造函数一般定义为公共的,但是派生类从来没有继承父类的构造函数。构造函数只能用于构造定义它的类。
2.sealed关键字:指定该类为密封类,防止作为基类被继承。
3.值类型总是密封的,不能作为基类被继承。所有结构是不能被继承的。
4.在子类构造函数中使用base调用父类的构造函数
public class T1
{
public string Id { get; set; }
public string Name { get; set; }
public T1()
{
}
public T1(string id, string name)
{
Id = id;
Name = name;
}
}
public class T2 : T1
{
public string FirstName { get; set; }
public string LastName { get; set; }
public T2()
{ }
public T2(string id, string name, string firstName, string lastName)
: base(id, name)
{
FirstName = firstName;
LastName = lastName;
}
}
5.包含/委托(非Delegate)
代码重用is-a:继承;has-a :包含
public class T3
{
T1 t1 = new T1();
public string GetName()
{
return t1.Name;
}
}
6.嵌套类型
可以直接在类或这结构的作用域内定义类型(枚举、类、接口、委托),被嵌套的类型(内部的)被认为是嵌套(外部的)类的成员,可以想操作其他成员一样来操作嵌套类型。
通过嵌套类型可以完全控制内部类型的访问级别,可以声明为私有的(通普通成员)。
由于嵌套类型是包含类的成员,所以(通普通成员)可以访问包含类的私有成员。
通常,嵌套类型只用作外部类的辅助方法,而不是为外部类所准备的,如果类型嵌套了另一个类类型,他就可以创建这个类型的成员变量。
7.virtual关键字
如果希望基类定义可以(不是必须)由子类重写的方法,就必须用virtual关键字修饰。
public class T3:T1
{
T1 t1 = new T1();
public override string Func1(string str1, string str2)
{
return t1.Func1(str1, str2);
}
}
8.密封虚成员
只希望防止派生类来重写某个方法
public override sealed string Func1(string str1, string str2)
{
return t1.Func1(str1, str2);
}
9.抽象类
尽管我们不能直接创建抽象类的实例,但是在创建其派生类时,仍然会在内存中对其进行组装。因此对抽象类来说,定义若干在分配派生类时间接调用的构造函数是很正常的。
10.成员的遮蔽
如果派生类定义的成员和定义在基类中的成员一致,派生类就遮蔽了父类的版本。可以为派生类的成员添加new关键字,显示的声明派生类型的实现故意设计为隐藏父类的版本。
public new void Draw()
{
//......
}
new 关键字可以应用到任何从基类继承的成员类型中(字段、常量、静态方法、属性等),但是仍然可以通过显示强制转换来访问被遮蔽的基类的成员。
Test t = new Test();
t.Draw(); //new遮蔽了父类的Draw方法,这里调用子类的
((base)t).Draw() ; //这里强制转换为父类,然后调用父类的Draw方法。
11.基类/派生类转换规则
如果两个类是is-a关系,在基类引用中保存派生类的类型总是安全的(隐式转换)。
使用C# 强制转换进行显示的向下转化。
object obj = new T1();
((T1)obj).Id = "1111"; //显示向下转化
12.System.Object
public virtual bool Equals(object obj);//默认情况下,如果被比较的项目,引用对象相同,返回true;
public vitrual string ToString(); //完全限定名返回对象的字符串表示。
public virtual int GetHashCode();//返回int值来标识指定的对象实例,默认,使用对象在内存中的当前位置来产生散列值。
如果重写一个类的Equals()方法,我们还需要重写默认的GetHashCode()实现,如果要构建要保存到Hashtable类型中的自定义类型,就应该重写这个成员。System.Collections.Hastable类在内部调用GetHashCode()来获取对象的位置,然后调用Equals()进行精确的匹配。String类已经有完善的散列码算法来使用String的字符数据计算散列值(因此,如果某个类的某个字段可以确保是唯一的,简便的方法就是调用这个字段的GetHanshCode得到散列值)。
2.sealed关键字:指定该类为密封类,防止作为基类被继承。
3.值类型总是密封的,不能作为基类被继承。所有结构是不能被继承的。
4.在子类构造函数中使用base调用父类的构造函数
public class T1
{
public string Id { get; set; }
public string Name { get; set; }
public T1()
{
}
public T1(string id, string name)
{
Id = id;
Name = name;
}
}
public class T2 : T1
{
public string FirstName { get; set; }
public string LastName { get; set; }
public T2()
{ }
public T2(string id, string name, string firstName, string lastName)
: base(id, name)
{
FirstName = firstName;
LastName = lastName;
}
}
5.包含/委托(非Delegate)
代码重用is-a:继承;has-a :包含
public class T3
{
T1 t1 = new T1();
public string GetName()
{
return t1.Name;
}
}
6.嵌套类型
可以直接在类或这结构的作用域内定义类型(枚举、类、接口、委托),被嵌套的类型(内部的)被认为是嵌套(外部的)类的成员,可以想操作其他成员一样来操作嵌套类型。
通过嵌套类型可以完全控制内部类型的访问级别,可以声明为私有的(通普通成员)。
由于嵌套类型是包含类的成员,所以(通普通成员)可以访问包含类的私有成员。
通常,嵌套类型只用作外部类的辅助方法,而不是为外部类所准备的,如果类型嵌套了另一个类类型,他就可以创建这个类型的成员变量。
7.virtual关键字
如果希望基类定义可以(不是必须)由子类重写的方法,就必须用virtual关键字修饰。
public class T3:T1
{
T1 t1 = new T1();
public override string Func1(string str1, string str2)
{
return t1.Func1(str1, str2);
}
}
8.密封虚成员
只希望防止派生类来重写某个方法
public override sealed string Func1(string str1, string str2)
{
return t1.Func1(str1, str2);
}
9.抽象类
尽管我们不能直接创建抽象类的实例,但是在创建其派生类时,仍然会在内存中对其进行组装。因此对抽象类来说,定义若干在分配派生类时间接调用的构造函数是很正常的。
public abstract class BaseClass { public int someProperty = 0; public BaseClass(int property) { this.someProperty = property; } }
public class ChildClass : BaseClass { public ChildClass(int property) : base(property) { } }
另外,尽管不能创建抽象基类的实例,完全可以使用抽象基类的变量来保存任何子类的引用。
10.成员的遮蔽
如果派生类定义的成员和定义在基类中的成员一致,派生类就遮蔽了父类的版本。可以为派生类的成员添加new关键字,显示的声明派生类型的实现故意设计为隐藏父类的版本。
public new void Draw()
{
//......
}
new 关键字可以应用到任何从基类继承的成员类型中(字段、常量、静态方法、属性等),但是仍然可以通过显示强制转换来访问被遮蔽的基类的成员。
Test t = new Test();
t.Draw(); //new遮蔽了父类的Draw方法,这里调用子类的
((base)t).Draw() ; //这里强制转换为父类,然后调用父类的Draw方法。
11.基类/派生类转换规则
如果两个类是is-a关系,在基类引用中保存派生类的类型总是安全的(隐式转换)。
使用C# 强制转换进行显示的向下转化。
object obj = new T1();
((T1)obj).Id = "1111"; //显示向下转化
12.System.Object
public virtual bool Equals(object obj);//默认情况下,如果被比较的项目,引用对象相同,返回true;
public vitrual string ToString(); //完全限定名返回对象的字符串表示。
public virtual int GetHashCode();//返回int值来标识指定的对象实例,默认,使用对象在内存中的当前位置来产生散列值。
如果重写一个类的Equals()方法,我们还需要重写默认的GetHashCode()实现,如果要构建要保存到Hashtable类型中的自定义类型,就应该重写这个成员。System.Collections.Hastable类在内部调用GetHashCode()来获取对象的位置,然后调用Equals()进行精确的匹配。String类已经有完善的散列码算法来使用String的字符数据计算散列值(因此,如果某个类的某个字段可以确保是唯一的,简便的方法就是调用这个字段的GetHanshCode得到散列值)。
相关文章推荐
- golang 长短连接处理
- android之bitmap-xml文件属性详解
- spring mvc IE8下JSP页面form表单提交后台不能获取值
- rebmuNtsegraL.179
- 258. Add Digits
- MySQL的连接查询及子查询
- UIView 的基本方法
- 软件工程作业01
- win10 下安装SQL server 2008R2 express
- 【转】【win网络编程】socket中的recv阻塞和select的用法
- 有关类方法调用的概括
- CodeForces 651A-Joysticks
- Learning Multi-Domain Convolutional Neural Networks for Visual Tracking
- JavaScript实现金额的大小写转换
- 分治策略-求最大连续子数组之和
- 237. Delete Node in a Linked List
- Fresco介绍 - 超级牛逼的android图片加载库
- 概率算法
- 2015年第六届蓝桥杯省赛(C/C++ B组)解题报告
- Tomcat启动报错 Failed to start component [StandardServer[8005]]解决