=抽象类=
虚方法
Person[] per = new Person[5];
Chinese ch1 = new Chinese();
Chinese ch2 = new Chinese();
Japanese jp1 = new Japanese();
Japanese jp2 = new Japanese();
Beijing bj1 = new Beijing();
per[0] = ch1;
per[1] = ch2;
per[2] = jp1;
per[3] = jp2;
per[4] = bj1;
class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public virtual void ShowNationality()
{
Console.WriteLine("我还没国籍,给你爹我个瑞士的");
}
}
//在父类,void前加一个virtual关键字(未加则表示子类不可能重写)。这就变成了虚方法。继承他的子类中如果不想显示这个,然后在子类中加override。这就叫方法重写:在父类中有一个方法,你想让他在子类中进行不同的实现
如下图:
//那么这就是如果这回他会先去吊重写的子类,如果你非要吊父类。就在中国子类加 base.ShowNationality(); 然后打印的时候就是就会一起把父类的打印出来了
class Chinese : Person
{
public string HuKou
{
get;
set;
}
显示国籍
public override void ShowNationality()
{
base.ShowNationality();
Console.WriteLine("中国");
}
}
class Japanese : Person
{
public void PoFu()
{
Console.WriteLine("剖腹");
}
public override void ShowNationality()
{
Console.WriteLine("日本");
}
总结:
//virtual关键字写在返回值前面,public virtual或 virtual public
//使用virtual关键字修饰的方法必须有实现{}
public virtual void ShowNationality()
{
}
//子类可以重写,也可以不重写
比如没有对中国人重写,啥几把也没有,那么他碰到中国人就会显示的是父类person的
//子类重写时使用overrid关键字
//注:方法重写时,方法签名必须与父类中的虚方法完全一致,否者重写不成功,其中包括“返回值”????????????
//虚方法的目的是为了方法重写,方法重写的目的是为了多态,多态是为了程序写好以后不需要,修改,拓展,要加美国人就直接写一个继承person,不需要修改调用代码或者person的代码。
public virtual void ShowNationality()
{
Console.WriteLine("我还没国籍,给你爹我个瑞士的");
}
上面这个东西,其实木有什么意义,因为他不是中国人就是日本人,也不会显示这个。我想不写,但是在这如果去掉{}是不对的。
我们以下关于抽象方法抽象类的东东————用abstract:
//父类中有的蛋蛋没有什么实现意义,一定会在子类重写。这种方法就用抽象方法
//抽象类不能new 不能实例化 不能通过base来调用????????
如下:
namespace 抽象类尝试
{
class Program
{
static void Main(string[] args)
{
Person[] per = new Person[4];//声明一个数组,即声明了五个per[1]=new chinese();
Chinese ch1 = new Chinese();
Chinese ch2 = new Chinese();
Japanese jp1 = new Japanese();
Japanese jp2 = new Japanese();
per[0] = ch1;
per[1] = ch2;
per[2] = jp1;
per[3] = jp2;
for (int i = 0; i < per.Length; i++)
{
per[i].ShowNationality();
}
Chinese p = new Chinese();
Console.ReadKey();
}
abstract class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
abstract public void ShowNationality();
}
class Chinese : Person
{
public string HuKou
{
get;
set;
}
public override void ShowNationality()
{
//base.ShowNationality();//不能实例化 不能通过base来调用
Console.WriteLine("中国");
}
}
class Japanese : Person
{
public void PoFu()
{
Console.WriteLine("剖腹");
}
public override void ShowNationality()
{
Console.WriteLine("日本");
}
}
}
}
//那么到现在啥时候用abstract啥时候用virtual呢?
如果程序中有可能把这个父类直接实例化来用,就不可以用抽象,如果在程序中绝对不可能实例化(???),只是为了来继承,那么久用抽象类。
//抽象类当中不是全都是抽象成员,里面也可以有实例成员。比如下:
abstract class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public void sayHello()
{
Console.WriteLine("hello");
}
abstract public void ShowNationality();
class Chinese : Person
{
public string HuKou
{
get;
set;
}
public override void ShowNationality()
{
Console.WriteLine("中国");
base.sayHello();
//this.sayHello();//也可以用this,一个是父类,一个是子类???
}
//这里吊的不是person的say hello,是子类中继承了say hello ,有了吊的它的
//抽象类中可以有抽象成员,也可以有非抽象成员你。但是一个类中有抽象成员,那么他就是抽象的了
//用virtual,子类可以也可以不用重写,而用abstract,子类必须重写,override
//抽象类中可以写virtual,算是个多余,抽象类
加一个
virtual public void test()
{
}
//抽象类的子类可以被new吧????27min
//Person p = new Chinese();//这样go的是go person,因为父类中有go方法,子类中我为重写
Chinese p = new Chinese();//这样go的是 go china
//p.go();
Console.ReadKey();
abstract class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
public void sayHello()
{
Console.WriteLine("hello");
}
abstract public void ShowNationality();
public void go()
{
Console.WriteLine("go person");
}
}
class Chinese : Person
{
public string HuKou
{
get;
set;
}
public override void ShowNationality()
{
Console.WriteLine("中国");
base.sayHello();
}
public void go()
{
Console.WriteLine("go china");//其实这里可以写成public new void go()
}
}
这样
一个问题:
class Beijing : Chinese
{
public override void ShowNationality()
{
Console.WriteLine("北京人很牛b");
}
}
//Beijing是个孙子类。爷爷学习好,父亲学习不好,问儿子你为啥学习不好,儿子说你都能重写我也能。
//如果父亲很严厉。北京人不能显示北京人很牛b就只能显示中国人:
class Beijing : Chinese
{
public new void ShowNationality()
{
Console.WriteLine("北京人很牛b");
}
}
//子类这个方法和父类一模一样,但是是个新的。即想重写就override,不想就用new
//但是呢,这会报错,因为在抽象类中必须得重写。然而在virtual中,子类不重写,而用new,是可以的。New这个东西一般其实也不常用
//子类用new的话,父类吊用不了子类的方法