Java第三周:继承和多态,抽象类和接口
目录
两个代码学会继承和多态,抽象类和接口
继承和多态
一、继承
二、多态
完整代码
抽象类和接口
一、抽象类
二、接口
概念
多实现
完整代码
继承和多态
一、继承
-
概念
-
继承是面向对象编程中的一种机制,它允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以在父类的基础上进行扩展,添加新的属性和方法,或者重写父类的方法。
-
例如,在Java中,使用
extends
关键字来实现继承关系。
-
// 定义父类Animal
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void makeSound() {
System.out.println("动物发出声音");
}
}
// 定义子类Dog,继承自Animal类
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
}
- 在这个例子中,
Dog
类继承了Animal
类。Dog
类继承了Animal
类的name
属性和getName
方法,并且添加了自己的bark
方法。 - 在Java中,
super
是一个关键字,用于指代父类对象。super(name)
这种用法通常出现在子类的构造函数中,用于调用父类的构造函数并传递参数。
二、多态
- 概念
- 多态是指同一个操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在面向对象编程中,多态主要通过方法重写和接口实现来体现。
- 例如,继续以上面的
Animal
和Dog
为例,我们可以有以下多态的体现:
// 定义子类Cat,继承自Animal类
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
}
@Override
是Java中的一个注解(Annotation)。它用于标识子类中的方法是重写(Override)父类中的方法。- 例如,在继承关系中,如果子类想要修改父类中已有的方法的实现,就需要重写该方法。使用
@Override
注解可以让编译器检查该方法是否正确地重写了父类中的方法。
完整代码
// 定义父类Animal
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void makeSound() {
System.out.println("动物发出声音");
}
}
// 定义子类Dog,继承自Animal类
class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
}
// 定义子类Cat,继承自Animal类
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog("旺财");
Animal animal2 = new Cat("小花");
animal1.makeSound();
animal2.makeSound();
}
}
- 继承关系
Dog
类和Cat
类都继承自Animal
类。它们通过super
关键字在构造函数中调用父类的构造函数来初始化从父类继承的name
属性。
- 多态体现
- 在
main
方法中,创建了Dog
和Cat
对象,但将它们赋值给Animal
类型的变量animal1
和animal2
。是多态的一种体现。 - 当调用
animal1.makeSound()
和animal2.makeSound()
时,根据对象的实际类型(分别是Dog
和Cat
),执行了各自类中重写后的makeSound
方法,而不是Animal
类中的makeSound
方法,这展示了多态性。
- 在
抽象类和接口
一、抽象类
概念
抽象类是一种不能被实例化的类,它主要用于为其他类提供一个通用的模板或框架。抽象类中可以包含抽象方法(只有方法签名,没有方法体)和非抽象方法。
- 抽象方法
- 抽象方法只有方法签名(方法名、参数列表、返回类型),没有方法体。它以
abstract
关键字修饰,并且抽象方法所在的类必须是抽象类。例如:
- 抽象方法只有方法签名(方法名、参数列表、返回类型),没有方法体。它以
abstract class Shape {
abstract double calculateArea();
}
- 在这个
Shape
抽象类中,calculateArea
就是一个抽象方法,它没有具体的实现,只是定义了一个计算形状面积的方法签名。这意味着任何继承Shape
类的子类都需要实现这个方法来提供具体的面积计算方式。
-
非抽象方法
- 抽象类也可以包含非抽象方法,这些方法有完整的方法体,可以提供一些通用的功能给子类。例如:
abstract class Shape {
public void printInfo() {
System.out.println("这是一个形状");
}
}
- 这里的
printInfo
方法是一个非抽象方法,它可以被子类继承并直接使用,为子类提供了一个通用的打印形状相关信息的功能。
抽象类定义了一组相关类的通用行为和属性。它通过抽象方法强制子类实现某些特定的方法,从而保证子类具有一定的一致性。例如,在图形相关的类层次结构中,所有的图形类(如圆形、矩形等)都应该有计算面积的方法,通过将calculateArea
定义为抽象方法,可以确保继承Shape
抽象类的子类都实现这个方法。抽象类中的非抽象方法可以被多个子类复用。例如,printInfo
方法可以在不同的图形子类中直接使用,无需在每个子类中重新编写相同的打印逻辑。
二、接口
概念
接口是一种特殊的抽象类型,它只包含方法签名、常量(默认是public static final
修饰的)和默认方法。接口定义了一组方法的规范,一个类可以实现一个或多个接口,表示这个类具有接口所定义的行为。
- 方法签名
- 只有方法签名没有方法体。例如:
interface Flyable {
void fly();
}
- 这里的
fly
方法就是接口Flyable
中定义的抽象方法,任何实现Flyable
接口的类都必须实现这个fly
方法。
- 常量
- 接口中的常量默认。例如:
interface Constants {
int MAX_VALUE = 100;
}
- 在这个
Constants
接口中,MAX_VALUE
是一个常量,它可以被实现这个接口的类直接使用。
- 默认方法
- 为了在接口中提供一些默认的实现,Java 8引入了默认方法。默认方法有方法体,可以在接口中直接实现一些通用的功能。例如:
interface Greetable {
default void greet() {
System.out.println("Hello!");
}
}
多实现
- 一个类可以实现多个接口,这与类的单继承(一个类只能有一个直接父类)不同。这使得类可以具有多种不同的行为。
class MyClass implements Serializable, Cloneable {
// 实现类的具体逻辑
}
- 这里
MyClass
类同时实现了Serializable
(可序列化)接口和Cloneable
(可克隆)接口,从而具备了可序列化和可克隆的能力。
完整代码
// 抽象类Shape
abstract class Shape {
// 抽象方法,计算面积
abstract double calculateArea();
// 非抽象方法,打印形状信息
public void printInfo() {
System.out.println("这是一个形状");
}
}
// 圆形类,继承Shape抽象类
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
double calculateArea() {
return Math.PI * radius * radius;
}
}
// 可飞行接口
interface Flyable {
void fly();
}
// 鸟类,实现Flyable接口并继承Object类(默认继承)
class Bird implements Flyable {
@Override
public void fly() {
System.out.println("鸟儿在飞翔");
}
}
public class Main {
public static void main(String[] args) {
Circle circle = new Circle(5.0);
circle.printInfo();
System.out.println("圆形面积: " + circle.calculateArea());
Bird bird = new Bird();
bird.fly();
}
}
在这个示例中:
- 首先定义了抽象类
Shape
,其中包含抽象方法calculateArea
和非抽象方法printInfo
。Circle
类继承Shape
类并实现了calculateArea
方法。 - 接着定义了接口
Flyable
,Bird
类实现了Flyable
接口并实现了fly
方法。 - 在
main
方法中,分别创建了Circle
和Bird
的实例,并调用了它们相应的方法,展示了抽象类和接口在实际代码中的应用。