Skip to main content

抽象类

似是而非,具备某种对象的特征但不具体。例如动物就是抽象类。

使用抽象类的好处:

使用抽象类把一种事物进行抽象,在调用的时候就会灵活很多,你只需要把对应的参数传递进去即可。

同时扩展性也很好,新增的只需要继承父类的抽象类,然后在调用时,把新增的类new出一个实例,把这个实例传进去就可以。

抽象类基本使用的示例:狗狗,动物,人类案例

你把狗狗当作动物来看
你把狗狗当作宠物来看

父类中的抽象方法就是对子类中的方法做了约束,也就是说子类中必须要有父类中定义的抽象方法。

抽象类可以对子类方法进行约束,子类方法中必须有这种方法,具体实现看子类个人。

抽象类的规则

  1. 抽象方法没有方法体,必须存在于抽象类,均使用 abstract 修饰。

  2. 抽象类不能直接new对象,必须通过new子类的方式创建对象(多态向上转型)。

  3. 子类必须重写抽象类中的所有抽象方法,除非子类也是抽象类。

  4. 抽象类中可以书写普通属性、普通方法、静态方法、构造方法。

  5. 抽象类作为父类,实现多态的方式与之前一致。

抽象类示例:

结构图

image-20250705104747795

image-20250705104851796

代码

package com.abstractClass.Test1;

// 定义一个抽象类
public abstract class Animal {
// 属性
private String animalType;
// 构造方法
public Animal(){}
public Animal(String animalType) {
this.animalType = animalType;
}
// 实例方法
public String getAnimalType() {
return animalType;
}
// 实例方法
public void setAnimalType(String animalType) {
this.animalType = animalType;
}
// 静态方法
public static void m1(){
System.out.println("Animal类中的m1方法 ");
}
// 抽象方法
public abstract void eat();
}

package com.abstractClass.Test1;

// 抽象类继承另一个抽象类
public abstract class Pet extends Animal{
// 定义一个抽象方法
public abstract void playWithMaster();
}

package com.abstractClass.Test1;

public class Tiger extends Animal{
@Override
public void eat() {
System.out.println("老虎吃肉");
}
}

package com.abstractClass.Test1;

public class Dog extends Pet{
// 重写父类中的抽象方法
@Override
public void playWithMaster() {
System.out.println("狗狗和主人玩飞盘");
}
// 重写爷类中的抽象方法
@Override
public void eat() {
System.out.println("狗狗吃骨头");
}
}

package com.abstractClass.Test1;

public class TestAnimal {
public static void main(String[] args) {
// 创建一个老虎对象
Animal tiger = new Tiger();
tiger.eat(); // 老虎吃肉

// 创建一个狗狗对象 父类引用是Animal类
Animal dog = new Dog();
dog.eat(); // 狗狗吃骨头,调用的是Dog类中重写的方法
// dog2.playWithMaster(); // 报错,Animal类中没有 playWithMaster() 方法

// 创建一个狗狗对象 父类引用是Pet类
Pet dog2 = new Dog();
dog2.eat(); // 狗狗吃骨头,调用的是Dog类中重写的方法
dog2.playWithMaster(); // 狗狗和主人玩飞盘,调用的是Dog类中重写的方法
}
}

抽象类实现多态

父类中的抽象方法就是对子类中的方法做了约束,也就是说子类中必须要有父类中定义的抽象方法。

结构图

image-20250705111919074

代码

package com.abstractClass.Test2;

public abstract class Door {
private String brand;
private double price;

public Door(String brand, double price) {
this.brand = brand;
this.price = price;
}

public Door() {
}

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

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

public abstract void close();

// toString重写

@Override
public String toString() {
return "Door{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}

package com.abstractClass.Test2;

public class CommonDoor extends Door{
@Override
public void open() {
System.out.println("普通门开门,插入钥匙,轻轻一转,zhi~ya一声,门开了");
}

@Override
public void close() {
System.out.println("普通门关门,随手关门,duang的一声,门关了");
}

}

package com.abstractClass.Test2;

public class SecurityDoor extends Door{
private String password;

public SecurityDoor(String password) {
this.password = password;
}

public SecurityDoor() {
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public void open() {
System.out.println("防盗门开门,输入密码,按下指纹,门自动打开");
}

@Override
public void close() {
System.out.println("防盗门关门,障碍物识别,自动关门");
}
}

package com.abstractClass.Test2;

public class Person {
// 定义实例方法
public void openCommonDoor(CommonDoor cd){
cd.open();
}

public void closeCommonDoor(CommonDoor cd){
cd.close();
}

public void openSecurityDoor(SecurityDoor sd){
sd.open();
}

public void closeSecurityDoor(SecurityDoor sd){
sd.close();
}

// 以上方式分别针对不同的门的种类编写了开和关的方法 如果后续有更多的门的种类
// 还需要继续编写更多的方法 这样设计不合理 不符合开闭原则
// 使用多态的方式简化

public void openDoor(Door door){
door.open();
}

public void closeDoor(Door door){ // 向上转型,父类引用指向子类对象,多态
door.close();
}
// 多态的情形2:返回值声明为 父类对象,实际返回值为子类类型
public Door buyDoor(double money){
if(money > 300){
return new SecurityDoor();
}else{
return new CommonDoor();
}
}
}

package com.abstractClass.Test2;

public class TestPersion {
public static void main(String[] args) {
Person person = new Person();
// 创建普通门实例
CommonDoor commonDoor = new CommonDoor();
commonDoor.setBrand("小金刚");
commonDoor.setPrice(200);
// 创建防盗门实例
SecurityDoor securityDoor = new SecurityDoor();
securityDoor.setBrand("大金刚");
securityDoor.setPrice(500);
// 人开门
person.openDoor(commonDoor);
person.openDoor(securityDoor);
// 人关门
person.closeDoor(commonDoor);
person.closeDoor(securityDoor);
System.out.println("-------------------------------------------------------");

// 多态情形1:向上转型,父类引用指向子类对象,多态
Door door = person.buyDoor(500); //
door.open(); // 门打开了
door.close(); // 门关闭了

// 多态情形3:父类类型数组,子类为元素
Door [] doors = new Door[2];
doors[0] = new CommonDoor();
doors[1] = new SecurityDoor();

// Door{brand='null', price=0.0}
// Door{brand='null', price=0.0}
for (int i = 0; i < doors.length; i++) {
System.out.println(doors[i].toString());
}
}
}