14. 类的关系——抽象
2024-04-10 00:00:27  阅读数 671

1、 Java抽象类

在继承中,抽象是一个非常重要的概念。 类可以是抽象的,方法也可以是抽象的。

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 如形状类是抽象的类,圆、三角形等是具体类。 用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。但是抽象类中不一定有抽象方法。 在面向对象的概念中,知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、 三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。

1.1抽象类的定义语法

[访问权限] abstract class 类名 { 成员列表 }

public abstract class Shapes {
public abstract void draw();
}

 public abstract class Shapes {
public void draw(){
//具体代码
}
}

1.2抽象类的注意描述

· 用abstract修饰的类就是抽象类

·如果有抽象方法,就必须把类定义为抽象类;但抽象类不一定有抽象方法。

·抽象类可以有成员属性和非抽象成员方法

·抽象类不可以被实例化,但可以有构造方法。(构造方法的作用用于子类对父类属性的赋值)。

·抽象类只能作为基类,表示一种继承关系。

·继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类的方法一样。否则,该类也必须声明为抽象类。

·构造方法和静态方法不可以修饰为abstract。

2、抽象方法

有时候,父类中的某一个方法,每一个子类都要去重写。这种情况下,父类中的这个方法,就没有必要有方法体,因为子类都不会直接使用,都要重写。

要强调,软件工程中,往往是要有需求分析,设计,再到编码。在设计阶段,设计人员要想办法让程序员知道某些类中应该实现哪些功能的,也就是what to do。父类往往都是设计人员设计的。因此不能把这样的方法删除掉,如果删除,就没有办法约束子类必须实现这些方法。这种时候,就把父类中的这样的方法的方法体去掉,就成为抽象方法。 抽象方法定义了what to do,而how to do在子类中实现。

2.1抽象方法的概念

在某些情况下,类无法(或者没有必要)提供方法的具体实现,可以将此方法声明成抽象方法;

在类中没有方法体的方法,就是抽象方法;

含有抽象方法的类,一定是抽象类。 抽象方法只需声明,而不需实现某些功能。

2.2抽象方法的语法

使用关键字abstract声明抽象方法,一般语法:

[访问权限] abstract 返回值类型 方法名称(参数列表);

如: public abstract void draw();

抽象方法的作用就是定义 How to do,而what to do留到子类去实现

2.3抽象的作用

·抽象最核心的作用是用来实现应用的可扩展性。 ·在面向对象领域,抽象类主要用来进行类型隐藏;也就是使用抽象的类型来编程,但是具体运行时就可以使用具体类型。 ·利用抽象的概念,能够在开发项目中创建扩展性很好的架构,优化程序。 ·抽象类,抽象方法,在软件开发过程中都是设计层面的概念。也就是说,设计人员会设计出抽象类,抽象方法,程序员都是来继承这些抽象类并覆盖抽象方法,实现具体功能。 例子:

人物穿装备和脱装备

场景:游戏中有一个人,人会有自己的装备位用来装装备,有个鞋子位和一个武器位,装备每个位置只能穿一件,如果穿第二件就会先把第一件脱了再穿上第二件,每次穿脱装备都会有属性的改变。

首先抽象出鞋子和武器统称为装备,先定义抽象类武器类

//装备抽象
public abstract class Equip {
    // 装备名
    private String name;

    // 攻击力
    private int atk;

    // 护甲值
    private int protectValue;

    public Equip() {
        // TODO Auto-generated constructor stub
    }

    //增加攻击力
    public abstract void addAtk(People people);
    
    
    //增加护甲值
    public abstract void addProtectValue(People people);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getProtectValue() {
        return protectValue;
    }

    public void setProtectValue(int protectValue) {
        this.protectValue = protectValue;
    }

    @Override
    public String toString() {
        return "Equip [name=" + name + ", atk=" + atk + ", protectValue=" + protectValue + "]";
    }

    
}

其次,定义鞋子类和武器类,继承装备抽象类

//鞋子类
public class Shoe extends Equip {

    public Shoe(String name, int atk, int protectValue) {
        // TODO Auto-generated constructor stub
        super.setName(name);
        super.setProtectValue(protectValue);
        super.setAtk(atk);
    }

    public void addAtk(People people) {
        // TODO Auto-generated method stub
        people.setAtk(people.getAtk() + this.getAtk());

        System.out.println("攻击力上升" + this.getAtk());

    }

    public void addProtectValue(People people) {
        // TODO Auto-generated method stub
        people.setProtectValue(people.getProtectValue() + this.getProtectValue());

        System.out.println("护甲值上升" + this.getProtectValue());

    }

}
//武器类
public class Weapon extends Equip {

    public Weapon(String name, int atk,int protectValue) {
        // TODO Auto-generated constructor stub
        super.setName(name);
        super.setProtectValue(protectValue);
        super.setAtk(atk);
    }
    @Override
    public void addAtk(People people) {
        // TODO Auto-generated method stub
        people.setAtk(people.getAtk() + this.getAtk());
        System.out.println("攻击力上升" + this.getAtk());
    }

    @Override
    public void addProtectValue(People people) {
        // TODO Auto-generated method stub
        people.setProtectValue(people.getProtectValue() + this.getProtectValue());
        
        System.out.println("护甲值上升" + this.getProtectValue());
        
    }   
    
}

再定义一个人类

//人类
public class People {
    
    //人物名字
    private String name;
    
    // 攻击力
    private int atk;

    //护甲值
    private int protectValue;
    
    //鞋子位
    private Shoe shoe;
    
    //武器位
    private Weapon weapon;
    
    public People(String name, int atk,int protectValue) {
        // TODO Auto-generated constructor stub
        this.name = name;
        this.atk = atk;
        this.protectValue = protectValue;
    }
    
    
    
    //穿装备
    public void putOn(Equip equip) {
        
        System.out.println(this.name + "捡了"+ equip.getName());

        //判断装备属于鞋子,是的话穿到鞋子位
        if (equip instanceof Shoe) {
            //判断鞋子位是否为空,不为空脱掉已穿的,更换鞋子
            if(this.getShoe()!= null) {
                this.getOff(this.shoe);
            }
            this.shoe = (Shoe)equip;
        }
        //判断装备属于武器,是的话穿到武器位
        else if(equip instanceof Weapon) {
            //判断武器位是否为空,不为空脱掉已带的,更换武器
            if(this.getWeapon()!= null) {
                this.getOff(this.weapon);
            }
            this.weapon = (Weapon)equip;
        }
        System.out.println(equip.toString());
        equip.addAtk(this);
        equip.addProtectValue(this);
        System.out.println(this.toString());
    }
    
    //脱装备
    public void getOff(Equip equip) {
        System.out.println(this.name + "脱了"+ equip.getName());
        System.out.println(equip.toString());
        System.out.println("攻击力下降" + equip.getAtk());
        
        this.setAtk(this.getAtk() - equip.getAtk());
        
        this.setProtectValue(this.getProtectValue() - equip.getProtectValue());
        System.out.println("护甲值下降" + equip.getProtectValue());
        System.out.println(this.toString());
        
        //判断装备属于鞋子
        if (equip instanceof Shoe) {
            //清空鞋子位
            this.shoe = null;
        }
        //判断装备属于武器
        else if(equip instanceof Weapon) {
            //清空装备位
            this.weapon = null;
        }
    }
    
    
    
    @Override
    public String toString() {
        return "People [name=" + name + ", atk=" + atk + ", protectValue=" + protectValue + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAtk() {
        return atk;
    }

    public void setAtk(int atk) {
        this.atk = atk;
    }

    public int getProtectValue() {
        return protectValue;
    }

    public void setProtectValue(int protectValue) {
        this.protectValue = protectValue;
    }



    public Shoe getShoe() {
        return shoe;
    }



    public void setShoe(Shoe shoe) {
        this.shoe = shoe;
    }



    public Weapon getWeapon() {
        return weapon;
    }



    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    
    
}

最后,我们来测试一下我们的穿脱装备

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        People people = new People("周凡", 0, 0);
        Shoe shoe = new Shoe("护甲鞋", 0, 100);
        Shoe shoe1 = new Shoe("攻速鞋", 0, 100);
        Weapon weapon = new Weapon("暴风大剑", 100, 0);
        
        people.putOn(shoe);
        people.putOn(shoe1);
        people.getOff(shoe1);
        people.putOn(shoe);
        people.putOn(weapon);
        
        people.getOff(weapon);
        
        
    }

}

结果:

周凡捡了护甲鞋
Equip [name=护甲鞋, atk=0, protectValue=100]
攻击力上升0
护甲值上升100
People [name=周凡, atk=0, protectValue=100]
周凡捡了攻速鞋
周凡脱了护甲鞋
Equip [name=护甲鞋, atk=0, protectValue=100]
攻击力下降0
护甲值下降100
People [name=周凡, atk=0, protectValue=0]
Equip [name=攻速鞋, atk=0, protectValue=100]
攻击力上升0
护甲值上升100
People [name=周凡, atk=0, protectValue=100]
周凡脱了攻速鞋
Equip [name=攻速鞋, atk=0, protectValue=100]
攻击力下降0
护甲值下降100
People [name=周凡, atk=0, protectValue=0]
周凡捡了护甲鞋
Equip [name=护甲鞋, atk=0, protectValue=100]
攻击力上升0
护甲值上升100
People [name=周凡, atk=0, protectValue=100]
周凡捡了暴风大剑
Equip [name=暴风大剑, atk=100, protectValue=0]
攻击力上升100
护甲值上升0
People [name=周凡, atk=100, protectValue=100]
周凡脱了暴风大剑
Equip [name=暴风大剑, atk=100, protectValue=0]
攻击力下降100
护甲值下降0
People [name=周凡, atk=0, protectValue=100]

通过上述简单的案例,我们总结了今天以及前几天学习的知识,活学活用,

希望明天的我们更加优秀!!!