C#中的继承,C#是面向对象语言,面向对象三种特性:封装、继承、多态。
这里主要是继承,这篇只是基础
首先定义一个基类:积累中含有一个使用virtual定义的一个虚方法。
virtual关键字用于在基类中修饰方法。virtual的使用会有两种情况:
1、在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
2、在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
virtual用虚方法标记:
a、可在派生类中以override覆盖此方法
b、不覆盖也可由对象调用
c、无此标记的方法(也无其他标记),重写时需用new隐藏原方法
实例:
class Program
{
static void Main(string[] args)
{
A a; // 定义一个a这个A类的对象.这个A就是a的申明类
A b; // 定义一个b这个A类的对象.这个A就是b的申明类
A c; // 定义一个c这个A类的对象.这个A就是b的申明类
A d; // 定义一个d这个A类的对象.这个A就是b的申明类
a = new A(); // 实例化a对象,A是a的实例类
b = new B(); // 实例化b对象,B是b的实例类
c = new C(); // 实例化b对象,C是b的实例类
d = new D(); // 实例化b对象,D是b的实例类
a.Func(); // 执行a.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类A,就为本身 4.执行实例类A中的方法 5.输出结果 Func In A
b.Func(); // 执行b.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,有重载的 4.执行实例类B中的方法 5.输出结果 Func In B
c.Func(); // 执行c.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类C,无重载的 4.转去检查类C的父类B,有重载的 5.执行父类B中的Func方法 5.输出结果 Func In B
d.Func(); // 执行d.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类D,无重载的(这个地方要注意了,虽然D里有实现Func(),但没有使用override关键字,所以不会被认为是重载) 4.转去检查类D的父类A,就为本身 5.执行父类A中的Func方法 5.输出结果 Func In A
D d1 = new D();
d1.Func(); // 执行D类里的Func(),输出结果 Func In D
Console.ReadLine();
}
}
class A
{
public virtual void Func() // 注意virtual,表明这是一个虚拟函数
{
Console.WriteLine("Func In A");
}
}
class B : A // 注意B是从A类继承,所以A是父类,B是子类
{
public override void Func() // 注意override ,表明重新实现了虚函数
{
Console.WriteLine("Func In B");
}
}
class C : B // 注意C是从A类继承,所以B是父类,C是子类
{
}
class D : A // 注意B是从A类继承,所以A是父类,D是子类
{
public new void Func() // 注意new ,表明覆盖父类里的同名类,而不是重新实现
{
Console.WriteLine("Func In D");
}
}
重载和重写的区别:
重写:通常,派生类继承基类的方法。因此,在调用对象继承方法的时候,调用和执行的是基类的实现。但是,有时需要对派生类中的继承方法有不同的实现。例如,假设动物类存在“跑"的方法,从中派生出马和狗,马和狗的跑得形态是各不相同的,因此同样方法需要两种不同的实现,这就需要"重新编写"基类中的方法。"重写"基类方法就是修改它的实现或者说在派生类中重新编写。
重载:在一个类中用相同的名称但是不同的参数类型创建一个以上的过程、实例构造函数或属性。
// 这里是重载
class Program
{
static void Main(string[] args)
{
string s = null;
show(s);
object a = "123";
show(a);
}
static void show(string s)
{
Console.WriteLine("string");
}
static void show(object o)
{
Console.WriteLine("object");
}
}
class tarce {
public void setWidth(int w)
{
width = w;
}
public void setHeight(int h)
{
height = h;
}
protected int width;
protected int height;
// Virtual虚方法
public virtual string GetResult()
{
return "我是一个虚方法";
}
}
定义一个派生类:继承了基类
class paisheng : tarce {
public int getArea()
{
return (width * height);
}
// 在派生类中重写Virtual虚方法
public override string GetResult()
{
return "我是在派生类中重写的虚方法";
}
}
调用以上两个类:
class Program
{
/* C#主要的运行函数,就是main函数 */
static void Main(string[] args)
{
paisheng pai = new paisheng();
pai.setWidth(12);
pai.setHeight(9);
int area = pai.getArea();
Console.WriteLine(area);
string str = pai.GetResult();
Console.WriteLine(str);
}
}
这里再墨迹一下:
Private:私有变量,只能自己调用,你儿子只能是你儿子
Protected:受保护的变量,你大爷永远是你大爷,但他也可能是别人的大爷。
Public:公共变量,公共电话,谁都能打。
测试使用全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace @virtual
{
class Program
{
static void Main(string[] args)
{
paisheng pai = new paisheng();
pai.setWidth(12);
pai.setHeight(9);
int area = pai.getArea();
Console.WriteLine(area);
string str = pai.GetResult();
Console.WriteLine(str);
Console.WriteLine("======================================================================");
A a; // 定义一个a这个A类的对象.这个A就是a的申明类
A b; // 定义一个b这个A类的对象.这个A就是b的申明类
A c; // 定义一个c这个A类的对象.这个A就是b的申明类
A d; // 定义一个d这个A类的对象.这个A就是b的申明类
a = new A(); // 实例化a对象,A是a的实例类
b = new B(); // 实例化b对象,B是b的实例类
c = new C(); // 实例化b对象,C是b的实例类
d = new D(); // 实例化b对象,D是b的实例类
a.Func(); // 执行a.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类A,就为本身 4.执行实例类A中的方法 5.输出结果 Func In A
b.Func(); // 执行b.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,有重载的 4.执行实例类B中的方法 5.输出结果 Func In B
c.Func(); // 执行c.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类C,无重载的 4.转去检查类C的父类B,有重载的 5.执行父类B中的Func方法 5.输出结果 Func In B
d.Func(); // 执行d.Func:1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类D,无重载的(这个地方要注意了,虽然D里有实现Func(),但没有使用override关键字,所以不会被认为是重载) 4.转去检查类D的父类A,就为本身 5.执行父类A中的Func方法 5.输出结果 Func In A
D d1 = new D();
d1.Func(); // 执行D类里的Func(),输出结果 Func In D
Console.ReadLine();
}
}
// 这是基类
class tarce
{
public void setWidth(int w)
{
width = w;
}
public void setHeight(int h)
{
height = h;
}
protected int width;
protected int height;
// Virtual虚方法
public virtual string GetResult()
{
return "我是一个虚方法";
}
}
// 这是派生类
class paisheng : tarce
{
public int getArea()
{
return (width * height);
}
// 在派生类中重写Virtual虚方法
public override string GetResult()
{
return "我是在派生类中重写的虚方法";
}
}
class A
{
public virtual void Func() // 注意virtual,表明这是一个虚拟函数
{
Console.WriteLine("Func In A");
}
}
class B : A // 注意B是从A类继承,所以A是父类,B是子类
{
public override void Func() // 注意override ,表明重新实现了虚函数
{
Console.WriteLine("Func In B");
}
}
class C : B // 注意C是从A类继承,所以B是父类,C是子类
{
}
class D : A // 注意B是从A类继承,所以A是父类,D是子类
{
public new void Func() // 注意new ,表明覆盖父类里的同名类,而不是重新实现
{
Console.WriteLine("Func In D");
}
}
}
有好的建议,请在下方输入你的评论。
欢迎访问个人博客
https://guanchao.site
欢迎访问小程序: