面向对象 方便以后的扩展和维护
封装 黑匣子 隐藏具体实现
继承
使代码可以重用
子类继承父类的属性和方法 :
单根继承性 继承具有传递性
所有的类都直接或间接的继承自Object
this 代表当前类的实例,base 代表父类的实例
protected
子类构造函数必须指明调用父类哪个构造函数
访问级别约束
子类的访问级别要比父类的低
方法、属性等暴露的返回值、参数的数据类型不能比方法、属性或者所在类的可访问级别低
下面为继承写一个简单的例子:
1 //练习:定义汽车类Vehicle属性(modelType,color,wheel)方法run,子类卡车(Truck) 属性weight载重 方法拉货,轿车 (Car) 属性passenger载客数量 方法载客 2 static void Main(string[] args) 3 { 4 Truck truck = new Truck(); 5 truck.LaHuo(); 6 Console.Read(); 7 } 8 //modelType,color,wheel)方法run 9 class Vehicle 10 { 11 public Vehicle() 12 { 13 } 14 public Vehicle(string modelType, string color, int wheel) 15 { 16 this.modelType = modelType; 17 this.color = color; 18 this.wheel = wheel; 19 } 20 private string modelType; 21 public string ModelType 22 { 23 get { return modelType; } 24 set { modelType = value; } 25 } 26 private string color; 27 public string Color 28 { 29 get { return color; } 30 set { color = value; } 31 } 32 private int wheel; 33 public int Wheel 34 { 35 get { return wheel; } 36 set { wheel = value; } 37 } 38 public void Run() 39 { 40 Console.WriteLine("正在行驶中,请勿打扰"); 41 } 42 } 43 class Truck:Vehicle 44 { 45 public Truck() 46 { 47 } 48 public Truck(string modelType, string color, int wheel) 49 :base(modelType,color,wheel) 50 { 51 } 52 public Truck(string modelType, string color, int wheel,float weight) 53 : base(modelType, color, wheel) 54 { 55 this.weight = weight; 56 } 57 private float weight; 58 public float Weight 59 { 60 get { return weight; } 61 set { weight = value; } 62 } 63 64 public void LaHuo() 65 { 66 //调用父类的方法 67 base.Run(); 68 Console.WriteLine("拉货"); 69 } 70 }
多态 不同对象执行同一行为(方法)有不同的表现
里氏替换原则
让父类引用指向子类对象
Person per = new Student();
per是父类的引用,它不知道有哪些子类
不能使用父类的引用,调用子类的成员
is if (shapes[i] is Circle) 判断对象是不是后面的类型
as Circle cir = shapes[i] as Circle; 如果转换失败返回null
抽象类和抽象方法 abstract
抽象类
不能被实例化的类 不能去new
!!抽象类用来实现继承 和 多态
抽象类定义的是公共的实现和能力(抽象方法,没有实现)
抽象类中可以包含抽象成员,也可以不包含
抽象类不能被密封
抽象方法
抽象方法不能有实现
抽象方法必须出现在抽象类中
抽象方法必须被子类重写(override),除非子类也是抽象类
下面做个简单的关于抽象类的练习:动物animal 都有吃eat和叫bark的方法,狗dog和猫cat叫的方式不一样
class Program { static void Main(string[] args) { //Animal[] animals = { // new Dog(), // new Cat(), // new Dog() // }; //foreach (Animal ani in animals) //{ // ani.Bark(); // ani.Eat(); //} Animal a = new Dog(); Bark(a); Console.Read(); } static void Bark(Animal ani) { ani.Bark(); } } abstract class Animal { public void Eat() { Console.WriteLine("eating"); } public abstract void Bark(); } class Dog:Animal { public override void Bark() { Console.WriteLine("汪汪"); } } class Cat:Animal { public override void Bark() { Console.WriteLine("喵喵·~"); } }
多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
虚方法 virtual,虚方法给父类提供了一种默认的实现,
子类可以使用override重写虚方法
虚方法不能出现在密封类(sealed)中
虚方法和抽象方法的区别
虚方法必须有实现,抽象方法不能有实现
抽象方法只能出现在抽象类中
抽象方法必须被子类重写(),虚方法可以被重写也可以不重写
(*)密封类 sealed 不能被继承的类,调用密封类成员更高效(调用sealed类的方法的时候
不用 看该方法是否被override了)
接口
接口是定义类的一组标准和规范
接口的出现是为了解决类的单根继承性
接口不能被实例化
可以同时实现多个接口,如果同时继承类和实现接口,类必须在最前
接口可以继承接口
接口中的成员不可以加访问修饰符,隐式为public
接口中的成员不能有实现
接口中的所有成员必须在子类中去直接实现
接口中可以包含属性、方法,但不能包含字段,构造函数
接口提供能力
接口污染,一个接口只做一件事情
interface IFlyable
{
void Fly();
void Speak();
}
接口和抽象类
抽象类中可以有实现而接口中不能有实现
抽象类和接口都不能被实例化
接口的成员在子类中直接实现,抽象类中的抽象成员要重写override
什么时候使用抽象类,什么时候使用接口
抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。
飞机会飞,鸟会飞,他们都实现了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。