多态 抽象类

本文探讨了实现多态的三种主要手段:虚方法、抽象类和接口。通过父类引用指向子类对象,可以实现代码的灵活性和可扩展性,允许调用子类特有的功能。多态有助于减少耦合,提高程序的可移植性。同时,文章通过示例解释了为什么父类引用不能直接调用子类特有的方法。最后,介绍了抽象类的概念及其在多态中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现多态的手段

1)、虚方法

步骤:

  1. 将父类的方法标记为虚方法 ,使用关键字 virtual,这个函数可以被子类重新写一个遍。

如 public virtual void Fly();

  1. 重写的子类加override,如public override void Fly();

2)、抽象类abstract

当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法。

3)、接口:实现接口的类,将接口中的方法实现

类型转换的另外一种方式

Person p =new Student() ;   Person p = new Person ( ) ;

//通过这种方式进行类型转换时,如果转换失败则直接报异常!  student s = (student) p;

//进行类型转换的另外一种方式

//通过as的方式进行类型转换,即便转换失败也不会报异常,而是返回一个null.

student s = p as student;

if (s!=null)

{
   console.writeLine ("转换成功! ") ;
}
else{
   console.writeLine ("转换失败! ");
}
console.writeLine ("ok" ) ;
console.Readkey () ;

父类引用指向子类对象:假设我有一个Animal类,和一个Dog类,则:Animal animal = new Dog();此为父类引用指向子类对象

1.为什么要用父类的引用指向子类的对象?

有句话我觉得很精辟:现在写的代码,被将来的代码调用,这都不算事。现在写的代码,能调用将来的代码,这才牛逼勒。

具体来说:假如有一个类,这个类需要实现吃各种水果的方法。那如果我们在类里面定义方法:

public  void eat(Banana banana) { }

public  void eat(Apple apple) { }

。。。。。。

这样就显得很麻烦,但要是我要是把这个方法写成: public void eat(Fruit fruit){}  这样只要继承Fruit或者实现Fruit接口,就都可以作为eat的参数。这样就简化了程序。

再比如:

写一个画图程序的时候,你想画方,画圆,画线。方,圆,线都属于Shape类型。那么就应该有

class Shape{}

class Fang extends Shape{}

class Yuan extends Shape{}

class Xian extends Shape{}

然后把他们画出来的方法在某个类里,这个方法接收一个图形,不管是什么样的形状,你只要给我一个图形,我就可以把它画出来,public void draw();

子类里面重写这个方法。如果你的参数定义成Shape s,那么就可以接受继承Shape的所有实际形状 public void draw(Shape s);这就实现了多态的概念。

2.这样做有什么意义?

子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

3为什么父类引用子类对象时,不能调用子类特有的方法?

比如说:

定义一个父类Animal,一个子类Bird,Bird有个独有的方法:飞行。我现在 Animal animal = new Bird    (); 你要调用 animal.fly();这是不符合逻辑的,因为动物不是都会飞。这就要回归到问题2:定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

4.这样做的好处是什么?

总的来说有三方面:一,实现多态。二,减小耦合。三,增加了程序的可移植性。

5.子类能覆盖父类的变量吗(父类引用指向子类对象时)?答案是不能

比如我在Animal中:int i =1;  在Dog中: int i = 1000 ;

然后 Animal animal = new Dog();

输出animal.i,结果为1.

抽象类

class Program
    {
        static void Main(string[] args)
        {
            //MyClass mc = new MyClass();
            MyClass mc = new MyClass1();
            mc.SayHi();
            Console.ReadKey();
        }

        //static void M1(Person p)
        //{
        //    p.SayHi();
        //}

        //static Person M2()
        //{

        //}
    }

    //3.抽象成员必须包含在抽象类中。
    //4.抽象类不能用来实例化对象,既然抽象类不能被实例化(不能new),那么抽象类的作用就是用来被“继承”的。继承的主要目的就是用来实现多态。
    abstract class MyClass
    {
        //1.抽象类中可以有实例成员,也可以有抽象成员

        public int Age
        {
            get;
            set;
        }

        //2.抽象成员不能有任何实现
        //5.抽象成员子类继承以后必须“重写”override,除非子类也是一个抽象类
        public abstract void SayHi();
    }

    class MyClass1 : MyClass
    {
        public override void SayHi()
        {
            Console.WriteLine("子类中的SayHi方法.");
        }
    }
    abstract class MyClass2 : MyClass
    {

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值