一、类的继承
1.类在功能上的拓展(extend)
2.只能有一个基类,但可以实现多个基接口
3.类访问级别对继承的影响
4.sealed类不能被继承
例1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp47
{
class Program
{
static void Main(string[] args)
{
//Type t = typeof(Car);
//Type tb = t.BaseType;
//Console.WriteLine(tb);
//验证Car是否派生自Vehicle
//当声明一个类时,默认是继承自object的
// -----------------------------------------
//Car car = new Car();
//Console.WriteLine(car is Vehicle);//True
//Console.WriteLine(car is Object);//True
//Vehicle vehicle = new Vehicle();
//Console.WriteLine(vehicle is Car);//False
//-----------------------------------------
//我们可以用一个父类类型变量引用一个子类类型实例
Vehicle vehicle = new Car();
Object o1 = new Vehicle();
Object o2 = new Car();
}
}
class Vehicle//在class前面加上sealed就会把这个类变成封闭类,不能够在作为基类
{
}
class Car : Vehicle//一个类只允许有一个基类;子类的访问级别不能超越父类的访问级别,但是可以跟父类访问级别持平
{
}
例2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp47
{
class Program
{
static void Main(string[] args)
{
Car car = new Car("");
Console.WriteLine(car.Owner);
}
}
class Vehicle
{
public Vehicle(string owner)//如果基类带有带参数的构造器,子类就会报错。解决方案如下
{
this.Owner = owner;
}
public string Owner { get; set; }
}
class Car : Vehicle
{
//方案一
//public Car():base("N/A")
//{
// this.Owner = "Car Owner";
//}
//方案二
public Car(string owner) : base(owner)
{
this.Owner = owner;
}
//为什么要这样写?因为实例构造器是无法继承的
public void ShowOwner()
{
Console.WriteLine(Owner);//this/base都一样,可以去掉
}
//class RaceCar : Car
//{
//}
}
}
例3:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyLib
{
public class Vehicle
{
private string Owner { get; set; }//类成员的访问级别是以类的访问级别为上限的,不可能超越类的访问级别
//public 为最公开级别,万人轮;internal 只能在本项目里面访问这个属性,无法再其他程序集访问这个属性;private只能在类体里面访问,可以继承但是不能访问
}
public class Car : Vehicle
{
public void ShowOwner()
{
//Console.WriteLine(Owner);//内部访问
}
}
public class C
{
}
}
例4:
类库
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyLib
{
public class Vehicle
{
protected int _rpm;
private int _fuel;//下划线表示私有字段
public void Refuel()
{
_fuel = 100;
}
protected void Burn(int fuel)//这个方法不应该public,因为“开车的人不并不需要知道燃料是怎么烧的”
{
_fuel -= fuel;
}
//为什么用protected?因为不想被外面调用,有希望能被子类调用(可跨程序集),这个时候就用protected
public void Accelerate()
{
Burn(1);
_rpm += 1000;
}
public int speed { get { return _rpm / 100; } }//没有set,只读属性
}
public class Car : Vehicle
{
public void TurboAccelerate()
{
Burn(2);
_rpm += 3000;
}
}
}
//小结:protected和internal可以一起用,顺序无所谓
//internal protected的意义:internal和protected是或的关系,表示既可以被它的派生类访问,又可以被程序集当中的所有其他类类访问
主程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MyLib;
namespace ConsoleApp48
{
class Program
{
static void Main(string[] args)
{
Car car = new Car();
car.Accelerate();
car.Accelerate();
Console.WriteLine(car.speed);
Car car1 = new Car();
car1.TurboAccelerate();
Console.WriteLine(car1.speed);
Bus bus = new Bus();
bus.SlowAccelerate();
Console.WriteLine(bus.speed);
}
}
class Bus : Vehicle
{
public void SlowAccelerate()
{
Burn(1);
_rpm += 500;
}
}
}
继承(刘老师):继承的本质是派生类已有成员的基础之上对基类进行横向或纵向上的扩展
PS:
1.类成员只能越来越多,无法减少。所以要小心加入类成员以免造成污染
2.名词解释
横向:指的是对类成员的扩充
纵向:对类成员版本更新或者说重写
二、成员的继承与访问
1.派生类对继承成员的访问
2.派生类对基类成员的访问
3.构造器的不可继承性
三、面向对象的实现风格
1.class-based,例如上面的例子,基于类的封装、继承和多态
2.prototype-based,基于原型的封装继承和多态