多态---虚方法 (子类可以选择重写或者不重写)
class Program { static void Main(string[] args) { Chinese cn1 = new Chinese("叶长种"); Chinese cn2 = new Chinese("王少伟"); Japanese jp1 = new Japanese("小野妹子"); American us = new American("勒布朗"); Person[] pers = { cn1, cn2,jp1,us }; for (int i = 0; i < pers.Length; i++) { Console.Write(pers[i].Name); pers[i].ShowNationality(); } Console.ReadKey(); } } public class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public virtual void ShowNationality() //虚方法virtual { Console.WriteLine("........"); } } public class Chinese : Person { public Chinese(string name) { this.Name = name; } public override void ShowNationality() // 子类重写父类方法时,使用的关键字是overrider { Console.WriteLine("【中国】"); } } public class Japanese : Person { public Japanese(string name) { this.Name = name; } public override void ShowNationality() { Console.WriteLine("【日本】"); } } public class American : Person { public American(string name) { this.Name = name; } public override void ShowNationality() { Console.WriteLine("【美国】"); } }
举例:
class Program { static void Main(string[] args) { Employee emp = new Employee(); emp.DaKa(); Manager man = new Manager(); man.DaKa(); Console.ReadKey(); } } public class Employee { public virtual void DaKa() //虚方法virtual { Console.WriteLine("员工8:30打卡。"); } } public class Manager : Employee { public override void DaKa() // 子类重写父类方法时,使用的关键字是overrider { Console.WriteLine("经理9:00打卡"); } }
虚方法特点总结:
1.在父类中把需要设置为虚方法的方法前加Virtual标记
2.虚方法在父类中必须有实现
3.子类继续父类后可以选择重写也可以选择不重写
4.当子类重写父类中的方法的时候,必须保证重写后的方法与原方法的访问修饰符,返回值类型,方法名,参数列表完全一致
5.当方法的标记是virtual或者override的时候都可以重写
静态
class Program { static void Main(string[] args) { Myclass mc = new Myclass(); //类中的静态成员不能通过对象来访问,只能通过“类名”来访问 //Myclass.name = "aaaa"; //Myclass.Say(); //静态成员在整个程序中是共享的,一个地方改变后,所有使用到的地方都发生改变 //静态成员直到程序退出时才会释放,在静态成员中不能使用this //M1(); //Console.WriteLine(Myclass.name); //Console.ReadKey(); MyTool.age = 100; MyTool.Show(); Console.ReadKey(); } static void M1() { Myclass.name = "aaaa"; } } //实例类(普通类) class Myclass { //静态成员 public static void Say() { Console.WriteLine("hello"); } //静态成员 public static string name; //实例成员 public int Age { get; set; } } static class MyTool { //静态构造函数,在第一次使用该类前调用(并且只调用一次) //静态构造函数不能有修饰符 //静态构造函数不能有参数(所以也不能重载) //主要是因为静态构造函数是系统调用的 static MyTool() { Console.WriteLine("第一次调用"); } public static void Show() { Console.WriteLine("show"); } public static int age; }
系统中 Math、Console、Convert等都是静态类!
静态类不能被其它类继承,静态成员亦不能被继承(访问的是同一个)
静态类只能继承Object类。(静态类不能继承自其它类)
继承(多态),静态本身就是相反的。
静态类不能实现任何接口,(因为接口中的成员都是实例成员)
sealed 密封类,不能被继承。 sealed是关键字!
静态类的本质就是abstract+sealed !
静态类,静态类成员:
1.静态成员在整个应用中共享同一个值。
2.只有当程序退出后,才释放静态资源的内存
3.静态成员只能通过类名来访问,不能通过对象名访问。
4.静态类不能被实例化
在实例类中使用静态成员:当该类需要被实例化时,并且该类中有某个成员是大家都共享的,此时,可以将该成员标记为static静态的。
静态类:当使用一些工具类的时候(都是一些工具方法),可以使用静态类来把相关的方法都封装到一个类中,方便调用。
class Program { static void Main(string[] args) { //1.将一个类标记为“密封类” //2.用在方法重写 } } //public sealed class Person //{ //} //public class Chinese : Person //不能继承 string是个密封类,是引用类型,滥用继承,会使系统崩溃! //{ //} public class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public virtual void Say() { Console.WriteLine("say....."); } } public class Chinese : Person { public override void Say() { Console.WriteLine("Chinese中的Say"); } } public class HeiBeiRen : Chinese { //终止继续重写 public sealed override void Say() { Console.WriteLine("河北人。。"); } } public class ShiJiaZhuang : HeiBeiRen { //不能再重写方法Say() }
多态:为了把程序的可扩展性,把不同的子类对象都当做父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化!
多态就是指不同对象收到不同消息时,会产生不同的行为,同一个类在不同的场合下表现出不同的行为特征!
开放封闭原则(对修改封闭,对扩展开放)
ToString()方法
class Program { static void Main(string[] args) { string s = "aaaa"; Console.WriteLine(s.ToString()); int n = 132; Console.WriteLine(n.ToString()); Console.ReadKey(); } }
里氏替换原则:
1.父类引用指向子类对象Person p=new Chinese();(隐式类型转换)
2.父类对象不能够替换子类Chinese c=(Chinese)new Person();(X)
is-a:可以用来验证继承关系是否合理(can-do验证实现接口是否合理)
if(obj is 类型A) //obj是父类类型对象,“类型A” 是子类类型
使用as进行类型转换,如果转换成功则返回成功后的对象,如果转换失败就返回NULL;
class Program { static void Main(string[] args) { Person p = new American("叶长种"); Chinese cn = p as Chinese; //使用as进行类型转换,如果转换成功则返回成功后的对象,如果转换失败就返回NULL; if (cn != null) { Console.WriteLine(cn.Name); } Console.ReadKey(); } } public class Person { public Person(string name) { this.Name = name; } public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } } public class Chinese : Person { public Chinese(string name) : base(name) { } } public class American : Person { public American(string name) : base(name) { } }
实现多态的方法
1.虚方法Virtual,子类重写父类中的方法。
2.抽象类abstract,子类重写父类中的方法。
3.接口,实现接口的类,将接口中的方法实现。
使用虚方法:
class Program { static void Main(string[] args) { Person p = new Chinese(); p.Say(); Console.ReadKey(); } } public class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public virtual void Say() { Console.WriteLine("Person类中的Say"); } } public class Chinese : Person { public override void Say() { Console.WriteLine("Chinese中的Say()"); } } public class American : Person { public override void Say() { Console.WriteLine("American中的Say()"); } }
使用抽象
class Program { static void Main(string[] args) { Person p = new Chinese(); p.Say(); Console.ReadKey(); } } //抽象类的特点: //1.抽象类不能被实例化。 //2.抽象类中可以有实例成员,也可以有抽象成员 public abstract class Person //抽象成员只能出现在抽象类中。所以要把当前类也变为抽象的 { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } //1. 关键字abstract //2.抽象成员不能有任何实现代码 //3.抽象成员只能出现在抽象类中。所以要把当前类也变为抽象的 //4.与虚方法不同,抽象方法子类必须重写(除非子类也是抽象的) public abstract void Say(); } public class Chinese : Person { public override void Say() { Console.WriteLine("Chinese中的Say()"); } } public class American : Person { public override void Say() { Console.WriteLine("American中的Say()"); } } //public class Japanese : Person //与虚方法不同,抽象方法子类必须重写 //{ //}
抽象类案例1
class Program { static void Main(string[] args) { Dog a = new Dog(); a.Eat(); a.Bark(); Console.ReadKey(); } } public abstract class Animal { public abstract void Eat(); public abstract void Bark(); } public class Dog : Animal { public override void Eat() { Console.WriteLine("我吃骨头"); } public override void Bark() { Console.WriteLine("汪汪汪"); } } public class Cat : Animal { public override void Eat() { Console.WriteLine("我吃鱼"); } public override void Bark() { Console.WriteLine("喵喵喵"); } }
抽象案例2:
class Program { static void Main(string[] args) { Teacher teacher = new Teacher(); Student student = new Student(); student.StandUp(); teacher.SayHello(); student.SayHello(); teacher.StandUp(); Console.ReadKey(); } } public abstract class Person { public abstract void SayHello(); public abstract void StandUp(); } public class Teacher : Person { public override void SayHello() { Console.WriteLine("同学们好"); } public override void StandUp() { Console.WriteLine("请坐"); } } public class Student : Person { public override void SayHello() { Console.WriteLine("老师好"); } public override void StandUp() { Console.WriteLine("起立"); } }
抽象案例3:
class Program { static void Main(string[] args) { Shape shape = new Circle(20); Console.WriteLine(shape.GetArea()); Console.WriteLine(shape.GetZhouChang()); Shape shape1 = new ChangFangXing(3, 4); Console.WriteLine(shape1.GetArea()); Console.WriteLine(shape1.GetZhouChang()); Console.ReadKey(); } } public abstract class Shape { public abstract double GetArea(); public abstract double GetZhouChang(); } public class Circle : Shape { //扩展属性 半径 public double R { get; set; } public Circle(double r) { this.R = r; } public override double GetArea() { return Math.PI * this.R * this.R; } public override double GetZhouChang() { return 2 * Math.PI * this.R; } } public class ChangFangXing : Shape { public double Width { get; set; } public double Heigh { get; set; } public ChangFangXing(double w, double h) { this.Width = w; this.Heigh = h; } public override double GetArea() { return this.Width * this.Heigh; } public override double GetZhouChang() { return 2 * (this.Width + this.Heigh); } }
抽象类练习:(U盘,MP3播放器,移动硬盘三种移动设备)
可移动设备类
//可移动存储设备 public abstract class MobileDisk { public abstract void Read(); public abstract void Write(); }
MP3类
public class MP3 : MobileDisk { public override void Read() { Console.WriteLine("MP3读取数据..."); } public override void Write() { Console.WriteLine("MP3写数据..."); } public void PlayMusic() { Console.WriteLine("音乐播放中..."); } }
U盘类
public class UDisk : MobileDisk { public override void Read() { Console.WriteLine("U盘读取数据..."); } public override void Write() { Console.WriteLine("U盘写数据...."); } }
硬盘类
public class HardDisk : MobileDisk { public override void Read() { Console.WriteLine("硬盘读取数据..."); } public override void Write() { Console.WriteLine("硬盘写数据...."); } }
计算机类
public class Computer { public MobileDisk Disk { get; set; } public void Read() { Disk.Read(); } public void Write() { Disk.Write(); } }
主程序
class Program { static void Main(string[] args) { Computer computer = new Computer(); //UDisk u1 = new UDisk(); //computer.Disk = u1; MP3 mp3 = new MP3(); computer.Disk = mp3; computer.Read(); computer.Write(); Console.ReadKey(); } }
抽象类练习:(橡皮鸭子,真实鸭子)
class Program { static void Main(string[] args) { } } public abstract class Duck { public void swim() { Console.WriteLine("鸭子在水上漂..."); } public abstract void Bark(); } public class RealDuck : Duck { public override void Bark() { Console.WriteLine("嘎嘎......"); } } public class RubberDuck : Duck { public override void Bark() { Console.WriteLine("唧唧......"); } }