111 - Lecture 8
Objects and Classes: Interfaces and Polymorphism
一、Objects
Objects are a data abstraction that captures
对象是一种数据抽象,包含两部分:
1. 内部表示(通过数据成员,如属性properties/attributes)
• Internal representation
2. 与其他对象交互的接口(通过方法定义行为,同时隐藏实现细节)
• Interface for interacting with other objects (defines behaviors via methods [procedures or functions], hiding the implementation details).
对象提供了与外界交互的接口或方法,例如 getTemperature()。
进一步解释
• 对象的核心在于封装性,即将数据和行为捆绑在一起,并隐藏对象内部实现细节,从而减少对外暴露的复杂性。
• 每个对象都有自己的状态(数据)和行为(方法)。外部代码可以通过调用对象的公共方法来操作对象的状态,而无法直接修改对象的内部数据,这确保了数据的安全性。
• 这种封装方式允许我们创建具有特定功能的“自给自足”的实体,不依赖外部的直接控制。
• public StoreManager(Distributor distributor) 是 StoreManager 类的构造函数。
• 它接收一个 Distributor 类型的参数,并将该参数赋值给类的私有成员变量 distributor。
StorManager manager = new StoreManager(new Distributor);
二、 Class Diagram
1. 类图是 UML(统一建模语言)的一部分,帮助可视化系统中各类的结构和关系,确保功能正确映射和集成。
a class diagram is a subset of unified modelling language(UML),to visualise the structure and relationships between different entities(classes) in the system,ensuring that all functionalities are correctly maped and integrates
2. 类图包括:
• 类的名称、属性和方法,以及它们的可见性修饰符(+ 表示 public,- 表示 private,# 表示 protected)。
3. Arrow is drawn to show an association between classes
• School 类可以通过 this.student 访问 Student 类的属性或方法。
School 可以发送消息给 Student,但 Student 不能发送消息给 School。
• School 类包含一个 Student 类型的对象 student,并在构造函数中对其进行了初始化。这意味着 School 可以通过 student 变量调用 Student 的方法和属性。
• 在 School 类的构造函数中,this.student 被初始化为一个新的 Student 实例,并将当前 School 对象 (this) 传递给 Student 对象的构造函数。
School can send messages to Student, and Student can send messages to School
三、 Interfaces
接口用于将具有类似功能的类分组,类似于没有实现的类声明:
• 接口中只有方法声明,而没有实现。
• An interface groups classes with similar capabilities and only includes method declarations, not implementations.
• 实现接口的类必须定义接口中声明的所有方法,否则会出现编译错误。
• Classes implementing an interface must define all declared methods or face compilation errors.
• 接口支持多继承,一个类可以实现多个接口,使得它能够同时表现出不同的行为,提供灵活性。
Example of Implementing an Interface
通过 implements 关键字,类可以实现接口的所有方法。
• 例如,Car 类实现了 Vehicle 接口,必须定义 move()、brake() 和 steer() 方法。
@Override
1. @Override is an annotation in Java
2. It is used to signal the compiler (and anyone reading your code) that the following method is an override of a method in an interface or superclass(父类).
3. The @Override annotation has no effect on how code behaves at runtime.
4. 使用 @Override 注解以确保正确实现接口的方法,避免拼写错误或参数不匹配的问题。
misspelling a function name or not correctly matching parameters.
• 接口是类同意遵守的合同(contracts that classes agree to)
• 如果一个类选择实现给定的接口,它必须定义接口中声明的所有函数
• 如果类未实现接口中的所有函数,会产生编译错误
(Compilation errors arise when a class doesn’t implement one of the interface’s functions)
• 接口只声明函数,不定义它们的实现(Interfaces only declare, don’t define their functions)
• 实现接口的类负责提供这些函数的定义或实现(definitions/implementations)
• 接口只关注每个实现它的类是否定义了接口中声明的函数,而不关心如何定义
• 接口帮助我们建模(model)相似性(similarities)并确保一致性(consistency)
1. 通过实现接口,我们可以知道 Vehicle 接口应声明哪些函数,实现功能上的相似性
--similarities
2. 编译器可以确保所需的函数已定义,实现一致性
--consistencies
• 接口和类一样,也有自己的 .java 文件
• 函数签名和返回类型必须与接口中声明的一致,否则会出现编译错误(compilation error)
四、Polymorphism(poly = many, morph = forms)
多态性允许不同的类以相同的方式被引用和操作,是一种通用编码方法。
A way of coding generically provides a way of referencing multiple classes sharing abstract
functionality as acting as one generic type
• 多态性实现中包括变量的实际类型与声明类型,以及方法的动态解析。
Polymorphism involves declared type (interface) and actual type (class implementation), with method resolution happening at runtime based on the actual object type.
• 示例类 CityNavigator 中的 travel 方法展示了多态的应用
• 方法参数为 Vehicle vehicle,可以接受任何实现(implement)了 Vehicle 接口的实例(instance)
• 在调用 vehicle.move() 时,根据传入的实际对象(actual object)(如 Car 或 Bike),调用对应的 move() 实现
Actual vs Declared type
• Vehicle bmw = new Car(); 是多态的表现
• bmw 的声明类型(declared type)是 Vehicle,实际类型(actual type)是 Car
• Java 允许这种赋值(assignment),因为 Car 是 Vehicle 的实现类(implementation)
• 可以将 Car 和 Bike 的实例视为 Vehicle 类型的实例
• 在语句 Vehicle bmw = new Car(); 中:
Car 是实际类型(actual type)
• 编译器会在 Car 类中查找(look in)任何调用的方法的定义
Vehicle 是声明类型(declared type)
• 编译器限制只能调用 Vehicle 接口中声明的方法
Question: If Car defines a playRadio() method, is it correct to call it?
由于 bmw 的声明类型是 Vehicle,你只能调用 Vehicle 接口中定义的方法,即使 Car 还实现了 playRadio() 方法。编译器会阻止你调用 bmw.playRadio(),因为 Vehicle 接口中没有 playRadio() 方法。这展示了多态中声明类型的约束。
Vehicle myRadio = new Radio(); 则不合法,除非 Radio 类也实现了 Vehicle 接口。否则,这段代码会出现编译错误,因为 Radio 不是 Vehicle 类型的实现类。
Motivation for Polymorphism
多态的应用:在大多数情况下,我们只关心不同对象的共享功能。
Polymorphism lets programmers sacrifice specificity for generality
▶ treat any number of classes as their lowest common denominator
▶ limited to methods declared in that denominator
Polymorphism in Parameters
1. travel() 方法接收任何实现了 Vehicle 接口的类作为参数。因此,任何实现了 Vehicle 的类实例都可以作为 travel() 方法的参数。
2. 由于 travel() 方法的参数类型是 Vehicle,所以它只能调用 Vehicle 接口中声明的方法,即只能访问 move()、brake()、steer() 等。
3. 即使传入的 Car 类或 Bike 类有其他方法(例如 playRadio() 或 kickstandUp()),也无法在 travel() 方法中直接调用它们。
1. Vehicle 是声明类型,而 Car 或 Bike 是实际类型。因此,vehicle.move() 的执行由实际类型决定,而不是声明类型。
2. 在 startTravel() 方法中,vehicle 是一个 Car 实例。因此,在运行时,Java 虚拟机(java virtual machine)会执行 Car 类中的 move() 方法。
五、Dynamic Binding
1. move() 方法在运行时动态绑定,这意味着编译器无法在编译时确定哪个 move() 方法会被调用。
2. 动态绑定(Dynamic Binding)允许相同的代码(如 vehicle.move())在每次执行时可能会解析为不同的具体方法(with different method resolution each time)。
3. 这种方法解析称为“动态绑定”,与“静态绑定”不同。静态绑定(static binding)在编译时确定,而动态绑定在运行时基于具体对象类型来确定。这种机制增强了多态的灵活性。
6. 动态绑定
Dynamic Binding
多态性通过动态绑定来实现,即编译器在运行时才决定具体调用哪个方法。
• Dynamic binding means the compiler decides which method to execute at runtime based on the object’s actual type, not the declared type.
六、Summary
• 接口是类的合约,定义功能但不关心实现。
• 多态性允许程序处理不同的类作为“通用类型”,提供实现无关的编程方式,便于扩展。
• Polymorphism allows treating different classes as their “generic type,” promoting more generic and extensible programming.