Java-18 抽象类

1.引入概念:用之前我们的猫和狗案例,动物举例,动物本身不应该是一个具体的东西,而且呢,动物类中的吃方法,睡觉方法这些都不应该也是具体的。我们现在,把一个不是具体的功能称之为抽象的功能,在Java中称之为抽象方法,而如果类中有抽象的方法,该类就必须定义为抽象类。

2.特点:

  1.抽象类和抽象方法必须用abstract关键字修饰

    格式 abstract class 类名 {}

       public abstract void eat();

/定义一个抽象类
abstract class Animal{
    //定义一个抽象的方法,名字叫吃,没有方法体
    public abstract void eat();
    //下面这样定义抽象方法是错误的,{}代表空方法体,会报错,抽象方法不能有方法体
//    public abstract void eat(){};

    //定义一个抽象的方法,名字叫睡觉,没有方法体
    public abstract void sleep();
}

  2.有抽象方法的类一定是抽象类,抽象类不一定有抽象方法,抽象类里面可以有具体的实现方法

//由于类存在抽象方法,该类必须定义为抽象类
//class Demo{
//    public abstract void show();
//}
abstract class Demo{
    public abstract void show();

    public void show2(){
        System.out.println("这是在抽象类中的具体的方法");
    }
}

3.抽象类的实例化:

  1.按照多态的方式,首先要有继承关系,由具体的子类实例化。多态的形式实例化,我们在这里称之为:抽象类多态

4..抽象类的子态:

  1、如果是一个具体的子类,就必须重写所有的抽象方法
  2、如果是一个抽象的子类,可以不重写父抽象类的抽象方法,也可以有选择性的重写

package shujia.day1.day5;
//抽象方法
abstract class Anmial{
    public abstract void sleep();
    public abstract void eat();
}

//如果是一个具体的子类,就必须重写所有的抽象方法,快捷键alt+enter
 class Dog extends Anmial{
    @Override
    public void sleep() {
        System.out.println("侧着睡");
    }

    @Override
    public void eat() {
        System.out.println("吃骨头");
    }
}

//如果是一个抽象的子类,可以不重写父抽象类的抽象方法,也可以有选择性的重写
abstract class Cat extends Anmial{
    @Override
    public  void eat(){
        System.out.println("重写方法");
    }
}

public class AbstractDemo1 {
    public static void main(String[] args) {
        //Animal这个类是一个抽象类,而抽象类不能被实例化
//        Animal animal = new Animal();   error
        //用多态的形式进行实例化
        Anmial anmial=new Dog();
        anmial.sleep();
        anmial.eat();



    }
}

5.抽象类中的特点:

  1.成员变量: 可以是变量 也可以是常量

  2.构造方法: 有构造方法,但是不能实例化,就是不能创建对象   那么,构造方法的作用是什么呢? 用于子类访问父类数据的初始化

  3.成员方法: 可以有抽象方法 限定子类必须完成某些动作

        也可以有非抽象方法 提高代码服用性

/*
        抽象类中成员的特点:
            成员变量:可以是变量,也可以是常量
            构造方法:有构造方法
                但是抽象类又不能被实例化,有个构造方法有什么用呢?
                用于子类访问父类进行初始化
            成员方法:
                可以是具体的实现方法,也可也是抽象的方法
 */
//任何类没有父类就默认是Object的子类
abstract class Anmial2 extends Object{
    //抽象类又不能实例化, 用于子类访问父类进行初始化
    Anmial2(){};
    int num=10;//变量
    final int num1=20;//常量
    //抽象的方法
    public abstract void eat();
    //具体的实现方法
    public void sleep(){
        System.out.println("sleep");
    }
}

class Cat1 extends Anmial2{
    @Override
    public void eat() {
        System.out.println("fish");
    }
}

public class AbstrctDemo2 {
    public static void main(String[] args) {
        Anmial2 anmial2 = new Cat1();
        System.out.println(anmial2.num);//10
        System.out.println(anmial2.num1);//20
        anmial2.eat();//fish
        anmial2.sleep();//sleep
    }
}

6.abstrct不能和哪些关键词共存:

    private 冲突
    final 冲突
    static 冲突

abstract class Demo2{
    public abstract void show();

    //非法的修饰符组合: abstract和private
//    private abstract void show2();

    //非法的修饰符组合: abstract和final
//    final abstract void show3();

    //非法的修饰符组合: abstract和static
//    static abstract void show4();

}

例题:

package com.shujia.java.day12.abstract_code;

/*
        假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
        经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
        请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。

        分析:
            普通员工:
                姓名,工号,工资
                工作(敲代码)

            经理:
                姓名,工号,工资,奖金
                工作(做PPT)

        实现:
            抽象的员工类
            普通员工类
            经理类

 */

abstract class Staff{
    private String name;
    private String id;
    private int salary;

    public Staff() {
    }

    public Staff(String name, String id, int salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public abstract void work();
}

class GeneralWorker extends Staff{

    public GeneralWorker() {
    }

    public GeneralWorker(String name, String id, int salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("敲代码");
    }
}


class Manager extends Staff{

    private int bonus;

    public Manager() {
    }

    public Manager(String name, String id, int salary) {
        super(name, id, salary);
    }

    public int getBonus() {
        return bonus;
    }

    public void setBonus(int bonus) {
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println("做PPT");
    }
}

public class AbstractTest4 {
    public static void main(String[] args) {
        Staff s1 = new GeneralWorker("大虎","0001",14000);
        System.out.println(s1.getName()+"---"+s1.getId()+"---"+s1.getSalary());
        s1.work();

        Staff s2 = new Manager("小虎","00080",30000);

        //向下转型使用子类特有的方法
//        s2.setBounts();
        ((Manager)s2).setBonus(4000000);
        System.out.println(s2.getName()+"---"+s2.getId()+"---"+s2.getSalary()+"---"+((Manager) s2).getBonus());
        s2.work();


    }
}

 

上一篇:9.21日


下一篇:MS-TCN++