里氏替换原则

子类可以替换父类的位置,并且程序的功能不受影响

因为父类有的成员 子类对象都有,所以程序的功能不受影响

 

 

1、父类变量指向子类对象

2、当父类变量指向子类对象的时候 通过这个变量来调用同名的方法的时候,会调用父类的同名方法,,上图中的类型指针指的时父类的方法表,而这个指针是由变量的类型决定,上图中Person p类型是Person,所以指向Person的方法表

3、当1个父类变量指向子类的对象的时候,只能通过这个父类的对象调用父类对象的成员,子类对象独有的成员调用不到,为了多态

注:Student s2=new Person()(不行,不符合自动转换条件:数据类型兼容,目标类型大于源类型),但可以强制转换,语法上没错误,但是运行可能出现错误Person p1=new Person(); Student s2=(Student)p1;(强制转换条件(有可能丢失精度):数据类型兼容)例如Person p1=new Student (); Student s2=(Student)p1(这样转换才可以),强制转换的时候,除非父类变量确实指向了1个子类的对象才可以成功将这个父类变量对象转换为一个子类对象,Person p1除非p1确实指向Student对象,否则不能把p1转换为Student对象

 

Is关键字

用来判断指定的变量是否指定的类型,返回的时true 和 false

 

P is Student()//返回时真

P is object//返回时真

子类对象永远是父类类型

当父类变量指向子类对象的时候,这个父类变量是1个父类类型也是一个子类类型

没有继承关系的时候,is返回时false

Int i=12

i is int    //true

i is double    //false

is 只适合引用类型的判断

 

 

as关键字

as转换失败不报异常返回null

 

变量的类型决定可以调用那些成员,无论你指向那一个对象上图中s可以调用Student里面的成员

 

 

 装箱与 拆箱

int i=12;//将值类型转换为引用类型

object o =i;//引用与值类型转换

int j=(int)o

j=11

//i还是12

//装箱过程:

1、在堆中分配好内存,值类型各个字段所需要的内存量+额外成员

2、值类型的字段复制到新分配的内存

3、返回地址

装箱过程很耗性能,尽量避免装箱操作

 

拆箱:将引用类型转换为值类型

1、  获取已装箱的对象的各个字段的地址(发生拆箱操作)

一般情况下,紧跟拆箱后 将这些字段的值复制到栈空间的值类型中去

拆箱的效率比装箱高 因为拆箱不需要复制字段的值

 

用+号连接字符串的时候,内部会调用string.Concat方法将每一个串作为参数传递到这个方法中

方法重写

被virtual修饰的方法叫做虚方法

虚方法可以被子类重写,可以通过override关键字重写父类的虚方法

Public override void SayHi()

当父类变量指向子类对象的时候并且子类重写,调用的时子类重写的方法,如果子类没有重写调用的时父类的方法

Person p1=new Sturdent();

为了多态

开闭原则:对扩展开放,对修改关闭

 

 

View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 多态
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             //多态好处:对扩展开放,对修改关闭
14             string uins = "-";
15             JiSuan js = null;
16             switch (uins)
17             {
18                 case "+":
19                     js = new Jia(1, 3);
20                     break;
21                 case "-":
22                     js = new Jian(1, 3);
23                     break;
24                 case "*":
25                     js = new Cheng(1, 3);
26                     break;
27                 case "/":
28                     js = new Chu(6, 3);
29                     break;
30             }
31             Console.WriteLine(js.GetRes());
32             Console.ReadKey();
33         }
34     }
35 }
View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 多态
 8 {
 9     class JiSuan
10     {
11         public int Num1 = 0;
12         public int Num2 = 0;
13         public JiSuan(int n1, int n2)
14         {
15             Num1 = n1;
16             Num2 = n2;
17         }
18 
19         public virtual int GetRes()
20         {
21             return 0;
22         }
23 
24     }
25     class Jia:JiSuan
26     {
27         public Jia(int n1, int n2)
28             : base(n1, n2)
29         { }
30         public override int GetRes()
31         {
32             return base.Num1 + base.Num2;
33         }
34     }
35     class Jian:JiSuan
36     {
37         public Jian(int n1, int n2)
38             : base(n1, n2)
39         { }
40         public override int GetRes()
41         {
42             return base.Num1 - base.Num2;
43         }
44     }
45     class Cheng:JiSuan
46     {
47         public Cheng(int n1, int n2) : base(n1, n2) { }
48         public override int GetRes()
49         {
50             return base.Num1 * base.Num2;
51         }
52     }
53     class Chu:JiSuan
54     {
55         public Chu(int n1, int n2)
56             : base(n1, n2)
57         { }
58         public override int GetRes()
59         {
60             return base.Num1 / base.Num2;
61         }
62     }
63 }

 

多继承的时候

如果GuangDongRen重写,则调用GuangDongRen的sayhi()方法,如果没有则查看GuangDongRen父类Chinese,如果Chinese重写,则调用Chinese的sayhi()方法,否则调用person的sayhi()方法

为了多态

posted on 2012-12-12 12:30  陈谨  阅读(333)  评论(0编辑  收藏  举报