C#中的继承
1.继承是允许重用现有类去创建新类的过程,原则:一个类派生出来的子类具有这个类的所有公共属性
创建新类所根据的基础类称为基类或父类,新建的类则称为派生类或子类
2.继承C#中的类
C#不支持多重继承,如果未在声明中指定一个基类,则继承自System.Object
using System; namespace BaseConsole { #region 基类 public class Person { private string _name; private uint _age; public void GetInfo() { Console.WriteLine("请输入你的姓名和年龄"); _name = Console.ReadLine(); _age = uint.Parse(Console.ReadLine()); } public void DispInfo() { Console.WriteLine("尊敬的{0},你的年龄为{1}",_name,_age); } } #endregion #region 派生类 public class Student : Person { private string _school; private uint _eng; private uint _math; private uint _sci; public void GetMarks() { Console.WriteLine("请输入学校名称"); _school = Console.ReadLine(); Console.WriteLine("请分别输入英语,数学和自然科学的分数。"); _eng = uint.Parse(Console.ReadLine()); _math = uint.Parse(Console.ReadLine()); _sci = uint.Parse(Console.ReadLine()); Console.WriteLine("所得总分为:{0}",_eng+_math+_sci); } } #endregion public class Exercise { [STAThread] static void Main(string[] args) { Student objStudent = new Student(); objStudent.GetInfo();//访问基类成员 objStudent.DispInfo();//访问基类成员 objStudent.GetMarks(); Console.ReadKey(); } } }
结果:
3.调用基类的构造函数
构造函数用于实例化类的成员字段,
base 关键字用于从派生类中访问基类成员,可以使用base 关键字调用基类的构造函数,不能访问基类的静态方法
using System; namespace BaseConsole { public class Persons { public string _name; public uint _age; //基类提供函数以进行初始化 public Persons(string name,uint age) { this._name = name; this._age = age; Console.WriteLine(_name); Console.WriteLine(age); } } public class Students : Persons { private uint _id; //调用Persons构造函数 public Students(string name, uint age, uint id) : base(name,age) { this._id = id; Console.WriteLine(_id); } } public class Exercises { [STAThread] static void Main(string[] args) { Students objStudent = new Students("dong",22,001); Console.ReadKey(); } } }
4.C#中方法的重写
”重写“ 基类方法就是修改它的实现或者说在派生类中对它进行重新编写
关键字 override
override 关键字用于修改方法,基类中的同名方法必须声明为virtual或abstract类型,加virtual 关键字表示可以在派生类中重写它的实现
new、static、virtual 关键字不能与override 访问修饰符一同使用
关键字new
new访问修饰符用于显式隐藏继承自基类的成员,即如果派生类成员的名称与基类成员名称相同,new会将派生类成员识别为一个全新的成员
using System; namespace BaseConsole { class Employees { public virtual void EmpInfo() { Console.WriteLine("该方法显示职员信息"); } } class DervEmployee : Employees { public override void EmpInfo() { base.EmpInfo(); Console.WriteLine("该方法重写了base方法"); } } class Test { [STAThread] static void Main(string[] args) { DervEmployee objDervEmployee = new DervEmployee(); objDervEmployee.EmpInfo(); Employees objEmployees = objDervEmployee; objEmployees.EmpInfo(); Console.ReadKey(); } } }
结果:
5.抽象类和抽象方法
抽象类是指至少包含一个抽象成员(尚未实现的方法)的类,抽象类不能实例化,抽象类是派生类的基础,通过不实现或部分实现,这些抽象类用于创建蓝本或者说模板,以派生出其他类
一个抽象类可以包含抽象方法和非抽象方法,抽象方法的目的在于指定派生类必须实现与这一方法关联的行为,抽象方法只在派生类中真正实现
使用override 关键字可在派生类中实现抽象方法,经override声明重写的方法称为重写基类方法,其签名必须与override 方法签名相同
using System; namespace BaseConsole { //抽象类 abstract class ABC { public abstract void AFunc(); public void BFunc() { Console.WriteLine("非抽象方法!"); } } //派生类 class Derv : ABC { public override void AFunc() { Console.WriteLine("抽象方法!"); } } class AbstractTest { [STAThread] static void Main( string[] args) { Derv objB = new Derv(); objB.AFunc(); objB.BFunc(); Console.ReadKey(); } } }
结果:
6.接口
接口不能包含任何实现方法,接口的每种方法必须在派生类中实现
接口的作用在于指明实现此特定接口的类必须实现该接口列出的所有成员,有时候可以看成是类的“模具”
在声明一个接口时。需考虑以下几点:
接口主体只限于对方法、索引器以及属性的声明
接口不能包含字段、构造函数和常量等
接口成员是隐式公开的,如果对其显式指定访问级别,就会出现编译错误
接口中不能实现任何方法、属性或者索引器
接口名称需始终冠以大写字母"I"
using System; namespace BaseConsole { public interface IPict { int DeleteImage(); void DisplayImage(); } //派生自接口 public class MyImages : IPict { //第一个方法的实现 public int DeleteImage() { Console.WriteLine("DeleteImage 实现!"); return(5); } //第二个方法的实现 public void DisplayImage() { Console.WriteLine("DisplayName 实现!"); } } class interfaceTest { [STAThread] static void Main(string[] args) { MyImages objM = new MyImages(); objM.DisplayImage(); int t = objM.DeleteImage(); Console.WriteLine(t); Console.ReadKey(); } } }
结果: