【总结】-多态

前言:

  前面总结了继承,接下来大概了解下多态,多态是可以表现多个类型的能力—一个事物可以做多种不同的事情,表现为"一个接口,多个功能";

What?:

  多态正如字面意思,多种形态,同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法,允许将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作;

重载:

  重载是在同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同,就是签名不同,签名由方法名和参数组成。能通过传递不同参数来决定到底调用哪一个同名方法;

  • 方法同名,但参数列表不同
  • 返回值类型不同步可以构成重载–签名不包括返回值
  • 同名方法返回值的类型要相同,否则不能重载
  • 方法的异常类型和数目不会影响重载
static void Main(string[] args)
{
    Printdata p = new Printdata();         
    p.print(6);            // 调用 print 来打印整数
    p.print(3.414);      // 调用 print 来打印浮点数
    p.print("Hello 小仙女,你好哦");  // 调用 print 来打印字符串   
    Console.ReadKey();
}

重写:

  基类方法中使用virtual关键字声明方法和派生类中使用override关键字声明方法名称相同,参数列表也相同,重写也就是相当于重新声明,会覆盖原来的方法和参数;

  • 方法同名,且参数列表相同;
  • 基类方法和派生类方法的签名相同,实现了派生类重写基类中的同名方法
  • 不能使用static修饰
  • 完善子类的方法名与父类的方法名重名出现一条绿线
public class Person
    {
        public override string ToString()
        {
            return "小仙女可爱的都冒泡了";
        }        
    }

隐藏:

  基类中的方法不声明virtual,在派生类中声明与基类同名时,需要使用new关键字,以隐藏基类同名方法

class Program
{
    static void Main(string[] args)
    {
        Teacher t = new Teacher();  
        t.Show();
    }
}

public new void Shout()
{
    Console.WriteLine("Dog Shout");
}

抽象方法抽象类:

  • public abstract void Show(); 抽象方法
  • 抽象方法没有方法体 只有—public abstract void Show();
  • 抽象方法必须在抽象类中;
  • 抽象类无法实例化;
  • 父类是抽象类,子类继承了这个类,必须把这个抽象类中的抽象方法重写;
public abstract class Animal
    
public class Pig :Animal
{
    public override void Shout()  //抽象方法
    {
        Console.WriteLine("哼哼叫");
    }
}

接口:

  • 是一种规范;接口不能直接实例化 ,不包含方法的实现,接口可以多继承,类只能单继承;
  • 接口,类,结构都可以从多个接口继承,
public class Student:IFly    //单继承
{
    public void SayHello()
    {
        Console.WriteLine("我是学生");
    }
    public void IFly()
    {
        Console.WriteLine("我会飞");
    }
}

 public class Teacher : Person,IFly //多接口继承
{
    public void Say()
    {
        Console.WriteLine("hellow,我是老师");
    }
    public void IFly()
    {
        Console.WriteLine("我会飞");
    }
}

静态与非静态比较:

这里写图片描述

虚方法与抽象方法比较:
这里写图片描述

<think>我们正在讨论Dart语言中类的多态性用法。多态面向对象编程的三大特性之一,它允许我们使用父类的引用指向子类的对象,并在运行时根据实际的对象类型调用相应的方法。这样,我们可以编写出更通用、更灵活的代码。 根据提供的引用,我们可以总结Dart中多态的使用方法如下: 1. **定义抽象类或父类**:首先需要定义一个抽象类(使用`abstract`关键字)或一个普通父类,其中声明一些方法(可以是抽象方法,也可以有默认实现)。抽象方法没有方法体,必须在子类中被实现。 2. **创建子类**:创建继承自抽象类或父类的子类,并实现父类中定义的抽象方法(如果父类中有抽象方法)。子类可以根据需要提供不同的实现。 3. **使用父类引用指向子类对象**:在代码中,我们可以声明一个父类类型的变量,然后将其指向一个子类的对象。这样,通过这个父类引用调用方法时,实际执行的是子类中重写的方法。 下面通过一个具体的例子来说明: ```dart // 定义一个抽象类Animal abstract class Animal { void eat(); // 抽象方法,没有方法体 } // 子类Cat class Cat extends Animal { @override void eat() { print('Cat eating...'); } } // 子类Dog class Dog extends Animal { @override void eat() { print('Dog eating...'); } } // 一个接收Animal类型参数的函数 void feedAnimal(Animal animal) { animal.eat(); // 这里会调用具体子类的eat方法 } void main() { var cat = Cat(); var dog = Dog(); feedAnimal(cat); // 输出: Cat eating... feedAnimal(dog); // 输出: Dog eating... } ``` 在这个例子中: - `Animal`是一个抽象类,它定义了一个抽象方法`eat`。 - `Cat`和`Dog`是`Animal`的子类,它们分别实现了`eat`方法,提供了不同的行为。 - 函数`feedAnimal`接收一个`Animal`类型的参数。当我们传递`Cat`对象时,它调用`Cat`的`eat`方法;传递`Dog`对象时,它调用`Dog`的`eat`方法。这就是多态的体现:同一个函数调用,根据传入的对象不同,执行不同的操作。 **多态的好处**: - 提高代码的可扩展性和可维护性。如果需要添加新的动物类型,只需要创建新的子类并实现`eat`方法,而无需修改`feedAnimal`函数。 - 使代码更符合现实世界的逻辑,因为不同的对象对同一消息可以有不同的响应。 此外,在Dart中,多态也可以与接口结合使用。Dart的接口是通过抽象类来隐式定义的,一个类可以实现多个接口(即多个抽象类),从而具备多种行为。例如: ```dart // 定义两个接口 abstract class Flyable { void fly(); } abstract class Swimmable { void swim(); } // Bird类实现两个接口 class Bird implements Flyable, Swimmable { String name; Bird(this.name); @override void fly() { print('$name is flying!'); } @override void swim() { print('$name is swimming!'); } } void main() { Bird bird = Bird('Sparrow'); bird.fly(); // 输出: Sparrow is flying! bird.swim(); // 输出: Sparrow is swimming! } ``` 在这个例子中,`Bird`类实现了`Flyable`和`Swimmable`两个接口,因此它必须实现这两个接口中定义的所有方法。这样,`Bird`对象就可以被当作`Flyable`或`Swimmable`类型来使用,这也是多态的一种应用。 总结:在Dart中,多态的使用主要依赖于继承和接口实现。通过父类引用指向子类对象,我们可以编写出通用的代码,而具体的行为由子类决定。 §§相关问题§§ 1. Dart中抽象类和接口有什么区别? 2. 在Dart中如何实现多个接口? 3. 多态在Dart中的实际应用场景有哪些? 4. 除了多态,Dart中面向对象编程的其他两大特性(封装和继承)如何实现?</think>### Dart 中类的多态性用法详解 多态面向对象编程的核心特性之一,在 Dart 中通过**父类引用指向子类对象**实现。其核心机制是:**编译时类型为父类,运行时类型为子类**,系统自动调用实际子类的方法实现。以下是具体使用方法: #### 1. **定义抽象类与抽象方法** ```dart abstract class Animal { void eat(); // 抽象方法(无方法体) void move() => print("Moving"); // 可包含具体方法 } ``` #### 2. **子类实现多态** ```dart class Cat extends Animal { @override void eat() => print("Cat eats fish"); // 实现抽象方法 void purr() => print("Purring"); // 子类特有方法 } class Dog extends Animal { @override void eat() => print("Dog eats bone"); // 不同实现 } ``` #### 3. **多态调用示例** ```dart void feedAnimal(Animal animal) { animal.eat(); // 动态绑定到实际子类方法 // animal.purr(); // 错误!父类引用无法访问子类特有方法 } void main() { Animal myPet = Cat(); // 父类引用指向子类对象 feedAnimal(myPet); // 输出: "Cat eats fish" myPet = Dog(); // 指向不同子类对象 feedAnimal(myPet); // 输出: "Dog eats bone" [^1] } ``` #### 关键特性: 1. **动态绑定** 方法调用在运行时根据对象实际类型确定,如`animal.eat()`实际调用`Cat.eat()`或`Dog.eat()`。 2. **向上转型限制** 父类引用只能访问: - 父类声明的方法 - 子类重写的父类方法 *无法直接调用子类特有方法(如`purr()`)*。 3. **向下转型(需显式)** ```dart if (myPet is Cat) { myPet.purr(); // 输出: "Purring" } ``` #### 多态的优势: - **代码扩展性**:新增子类(如`Bird`)无需修改`feedAnimal`函数[^2] - **接口统一**:不同子类对象可用相同父类类型处理 - **解耦设计**:业务逻辑依赖抽象(Animal),而非具体实现 #### 实际应用场景 1. **插件系统**:定义统一接口,不同插件实现具体功能 2. **UI组件库**:基础组件类声明`render()`,不同组件重写渲染逻辑 3. **算法策略**:抽象策略接口,运行时切换具体算法实现[^3]
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值