纲要
- 类声明的全貌(声明既定义)
- 最简单的类声明(类的访问控制)
- 类成员的访问控制
- 类的继承
- 派生类对基类的成员获得与访问
- 在派生类中访问基类的成员
- 构造器的不可继承性
类声明的全貌(Class declarations)
C#有一个全局名称空间,项目中不要使用
Class Modifiers
using System;
using System.Collections.Generic;
using System.Text;
namespace MyLib.MyNamespace //文件夹的名字相当于名称空间的名字,MyLib大名称空间 MyNamespace子名称空间
{
public class Calculator //class关键字 Calculator类名 {}类体 前面默认为internal关键词
{
//internal关键词可以在一个项目中自由访问的,项目级别(Assembly)程序集
public double Add(double a,double b)
{
return a + b;
}
}
}
Tip.net standard2.0 要使用.net framework 4.6.1以上才能引用。
优质代码
优质的开源项目代码就是最好的参考,经常阅读高手写的代码,不但能提高自己理解代码的能力,还能渐渐养成写出漂亮代码的习惯,先临后摹。
类的继承
- 类在功能上的扩展
- 只能有一个基类,但可以实现多个其接口
- 类访问级别对继承的影响(子类的访问级别不能超越父类的访问级别)
- sealed类不能被继承(sealed封闭类,不能用来当作基类)
继承的现象
基类-派生类 父类(parent class)-子类(child class)
查看是否具有继承关系: ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace HelloOOP { class Program { static void Main(string[] args) { Type type = typeof(Car); Type type1 = type.BaseType; Console.WriteLine(type1.FullName); } }
class Vehicle
{
}
class Car:Vehicle
{
}
}
<a name="pEWq5"></a>
### 是一个 is a 一个子类的实例从语义上来说也是一个父类的实例<br />
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloOOP
{
class Program
{
static void Main(string[] args)
{
//是一个 is a 一个子类的实例从语义上来说也是一个父类的实例
Car car = new Car();
Console.WriteLine(car is Vehicle); // Result is true
}
}
class Vehicle
{
}
class Car:Vehicle
{
}
}
可以用父类类型的变量来引用一个子类类型的实例(多态)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloOOP
{
class Program
{
static void Main(string[] args)
{
//是一个 is a 一个子类的实例从语义上来说也是一个父类的实例
//可以用一个父类类型的变量来引用子类类型的实例(多态)
Vehicle vehicle = new Car();
Object o = new Vehicle();
Object o1 = new Car();
}
}
class Vehicle
{
}
class Car:Vehicle
{
}
}
继承的本质
继承的本质是派生类在基类已有成员的基础上,对基类进行的横向和纵向的扩展
横向扩展:类成员在数量上越来越多
纵向扩展:不增加类成员的个数,对某个类成员的版本进行更新(时间轴和时间线) **重写(Override)**
成员的继承与访问
类成员的访问级别
类成员的私有成员被继承但是无法访问而已
**protected 只有继承的子类才能被访问,访问级别是跨程序集的,多数应用在方法上,重写用的多。internal protected组合使用,既可以被派生类访问,又可以被程序集中所有的类访问。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Vehicel //如果没有向外可访问的类,则名称空间无法被using
{
public class Vehicle
{
private int _rpm;//下划线加变量名表示私有实例变量
public void Accelerate()
{
_rpm += 1000;
}
public int Speed { get { return _rpm / 100; } }
}
public class Car: Vehicle
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vehicel;
namespace HelloOOP
{
class Program
{
static void Main(string[] args)
{
Car car = new Car();
car.Accelerate();
car.Accelerate();
Console.WriteLine(car.Speed);
}
}
}
构造器的不可继承性
构造器会被覆盖,基类的构造器先被触发,然后触发子类的断点。
base关键字只能向上访问一层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloOOP
{
class Program
{
static void Main(string[] args)
{
Car car = new Car();
Console.WriteLine(car.Owner);
}
}
class Vehicle
{
public Vehicle()
{
this.Owner = "N/A";
}
public string Owner { get; set; }
}
class Car:Vehicle
{
public Car()
{
this.Owner = "Car Owner";
}
public void ShowOwner()
{
Console.WriteLine(base.Owner);//base关键字只能向上访问一级
Console.WriteLine(this.Owner);
}
}
class RaceCar:Car
{
}
}
class Vehicle
{
public Vehicle(string owner)
{
this.Owner = owner;
}
public string Owner { get; set; }
}
class Car:Vehicle
{
public Car(string owner):base(owner) //传一个值给基类的自定义构造器
{
this.Owner = "Car Owner";
}
public void ShowOwner()
{
Console.WriteLine(base.Owner);//base关键字只能向上访问一级
Console.WriteLine(this.Owner);
}
}