接口和多态

接口的定义:

    我们在学习继承的时候,知道子类是不可以继承多个父类的,但我们想要子类实现多个功能的时候,就可以使用借口来实现多继承的目的

   (1)接口使用interface关键字,而不是class关键字,可以把接口看作是抽象类;

一个完整接口的定义:

public interface A{

public static final  double PI = 3.14;//定义常量

public abstract void method();//定义抽象方法

}

   (2)接口只能有抽象方法和常量;

抽象方法使用abstract修饰,可以不用写方法体

public abstract int sum();用分号结尾,常量用public abstract final修饰,常量用大写字母

   (3)接口不能实例化对象

因为接口没有成员变量以及构造器,所以无法进行实例化对象

   (4)接口不能提供构造器

因为接口没有成员变量,所以不能提供构造器对成员变量进行初始化

接口在创建常量时。默认使用public static final修饰

接口在创建方法时,默认使用public abstract修饰

实现接口:

(1)子类可以实现接口中所有抽象方法;

(2)子类在没有实现接口中的所有抽象方法时,需要使用abstract修饰

(3)子类在实现接口时。使用implements关键字

(4)子类可以实现多个接口,中间用逗号隔开

如:

public class A implements B,C{}

(5)子类可以在继承父类的同时也可以实现一个或多个接口

如:

public class A extends B implements C,D{}

接口之间的继承

接口之间是继承关系,使用extends关键字,子接口可以继承父类所有的抽象方法

语法:

public interface A extends B{}

接口之间支持多继承

如:

public interface A extends B, C{}

接口与类之间的关系:

接口与接口之间是继承关系,可以多继承

接口与类是实现关系,类实现接口中的抽象方法,可以实现多个抽象方法

类与类之间是继承关系,只能单继承

注意:接口不可以继承类!

多态:

多态是指一个变量在不同的环境中有不同的体现,是面向对象特征之一;

(1)向上造型:

父类型的变量指向不同的子类时功能有不同的体现:

(因为子类在重写父类方法时,方法名相同,返回值类型可以相同,也可以是父类返回值类型的子类,方法内的逻辑子类可以自己改写,可以与父类不同)

如:

public class Test01{

    public Object run(){

    System.out.println("小狗汪汪汪");  

    return new Object;

    }

}

public class Test02 extends Test01{

    public String run(){

    System.out.printnln("小猫喵喵喵");

    return new String ;

    }

}

public class Test03 extends Test01{

     public Object run(){

    System.out.println("小鸡咕咕咕");

    return new Object;

 

    }

}

在这个父类中,有两个子类

Test01 p = new Test02();

p.run();//父类型的变量p指向Test02子类时,其实现的功能是:小狗汪汪汪

p = new Test03();

p.run();//父类型的变量指向Test03子类时,其实现的功能是:小鸡咕咕咕

(2)不同的父类型指向同一子类时,会有不同的功能

ZhengYangDoor a= new ZhengYangDoor();

a.theift();

a.open();

Enter a1 = a;

a1.open();

Outer a2 = a;

a2.theift();

子类在继承父类时,只能继承单个父类,但是继承具有传递性,子类可以继承父类的父类的基本特性,所以这些类在指向同一子类时会有不同的功能

向下造型:

将父类型的变量赋值给子类型或者其他父类(接口)

Animal animal = new Dog();

Dog dog = (dog)animal;

dog.eat();

Cat cat = (Cat) animal;//编译错误

cat.eat();

在这里会出现一种异常,类造型异常

java.lang.ClassCaseException;

原因是:Cat cat = (Cat)dog;

本来狗这个类与猫这个类有共同的父类,但是两个子类之间不能进行强转,会出现类造型异常,符合向下造型的只能是将父类(接口)赋值给子类型

为了防止出现类造型异常,我们可以先进性判断:

if(animal instanceof Cat){

Cat cat = (Cat)animal;

}else if(animal instanceof Dog){

Dog dog = (Dog)animal;

}

在这里先判断animal是否属于Cat类型,然后进行强转,不会出现类造型异常

 

 

 

### Python 中接口多态的实现方式及使用方法 #### 1. 多态的基础原理 在 Python 中,多态的核心理念基于动态类型系统鸭子类型[^1]。这意味着只要一个对象能够响应所需的方法调用,无论它的具体类型是什么,都可以认为它是有效的。这种灵活的设计使得 Python 的多态性更加直观且易于实现。 --- #### 2. 使用继承实现多态 通过继承机制,子类可以覆盖父类中的方法以提供特定的功能实现。当通过父类引用访问这些方法时,实际执行的是子类中定义的行为。 ```python # 定义一个基类 class Animal: def talk(self): raise NotImplementedError("Subclasses must implement this method") # 子类覆写talk方法 class Dog(Animal): def talk(self): return 'Woof!' class Cat(Animal): def talk(self): return 'Meow!' # 测试多态行为 def animal_speak(animal: Animal): print(animal.talk()) dog = Dog() cat = Cat() animal_speak(dog) # 输出 Woof! animal_speak(cat) # 输出 Meow! ``` 在这里,`Animal` 类作为一个抽象基类提供了统一的接口 `talk()`,而具体的实现则由各个子类负责完成。这种方式体现了典型的多态特征[^3]。 --- #### 3. 利用鸭子类型简化设计 由于 Python 支持鸭子类型,因此并不严格要求显式的继承关系也能达到类似的多态效果。只要有相同名称的方法就可以正常工作。 ```python class Laptop: def charge(self): return "Charging laptop..." class Phone: def charge(self): return "Charging phone..." def device_charge(device): return device.charge() laptop = Laptop() phone = Phone() print(device_charge(laptop)) # 输出 Charging laptop... print(device_charge(phone)) # 输出 Charging phone... ``` 此例说明即便 `Laptop` `Phone` 没有任何关联,但因为两者都有名为 `charge` 的方法,所以仍然可以通过通用函数 `device_charge` 来操作它们。 --- #### 4. 接口的隐式表达 Python 并不像一些静态语言那样拥有正式的接口关键字,但是可以通过 ABCs(Abstract Base Classes) 或协议(protocol) 来模拟接口的概念。ABCs 可用于强制某些类必须实现特定的方法才能实例化。 ```python from abc import ABC, abstractmethod class DeviceInterface(ABC): @abstractmethod def connect(self): pass @abstractmethod def disconnect(self): pass class BluetoothDevice(DeviceInterface): def connect(self): return "Bluetooth connected." def disconnect(self): return "Bluetooth disconnected." bluetooth_device = BluetoothDevice() print(bluetooth_device.connect()) # 输出 Bluetooth connected. print(bluetooth_device.disconnect()) # 输出 Bluetooth disconnected. try: interface_instance = DeviceInterface() # 尝试直接实例化会抛出异常 TypeError except Exception as e: print(e) # 输出 Can't instantiate abstract class ... ``` 这里展示了一个简单的设备连接断开的例子,其中 `DeviceInterface` 是一个抽象基类,只有在其所有抽象方法都被具体实现在子类之后才可以正常使用[^4]。 --- #### 5. 协议与数据类的应用 从 Python 3.8 开始引入的数据类(data classes),配合协议的支持,可以让开发者更方便地构建具有固定属性集合的对象,并自动获得诸如比较、字符串表示等功能。同时结合 typing 模块中的 Protocol ,可以进一步强化类型提示的同时保留灵活性。 ```python from dataclasses import dataclass from typing import Protocol class SpeakerProtocol(Protocol): volume_level: int def adjust_volume(self, level_change: int) -> None: ... @dataclass class Radio(SpeakerProtocol): volume_level: int def adjust_volume(self, level_change: int): self.volume_level += level_change print(f'Radio Volume adjusted to {self.volume_level}') radio = Radio(volume_level=50) radio.adjust_volume(-10) # 输出 Radio Volume adjusted to 40 ``` 这段代码片段演示了如何利用协议来描述期望的行为模式而不必关心确切的继承链路[^2]。 --- ### 总结 综上所述,Python 提供了多种途径来达成多态的目标,既可以依赖传统的继承结构也可以充分利用其独特的动态特性如鸭子类型等手段。无论是简单应用还是复杂架构下都能找到适合自己的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值