JavaSe之抽象类

抽象类的特点:
1、抽象类和抽象方法必须用abstract关键字修饰
格式:
abstract class 类名{}
abstract void eat();
2、抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类里面可以有具体的实现方法
3、抽象类不能实例化
那么,抽象类如何实例化呢?
按照多态的方式,首先要有继承关系,由具体的子类实例化。
多态的形式实例化,我们在这里称之为:抽象类多态
4、抽象类的子类
1、如果是一个具体的子类,就必须重写所有的抽象方法
2、如果是一个抽象的子类,可以不重写父抽象类的抽象方法,也可以有选择性的重写

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

abstract class Demo{
    public abstract void show();

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


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

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

//abstract class Demo2 extends Animal{
//    @Override
//    public void eat() {
//        System.out.println("重写方法");
//    }
//}

//快捷键 alt + enter
class Cat extends Animal{

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

    @Override
    public void sleep() {
        System.out.println("趴着睡");
    }
}



public class AbstractDemo1 {
    public static void main(String[] args) {
        //Animal这个类是一个抽象类,而抽象类不能被实例化
//        Animal animal = new Animal();

//        Cat cat = new Cat();
//        cat.eat();
//        cat.sleep();

        //用多态的形式进行实例化
        Animal a1 = new Cat();
        a1.eat();
        a1.sleep();
    }
}

抽象类中成员的特点:
成员变量:可以是变量,也可以是常量
构造方法:有构造方法
但是抽象类又不能被实例化,有个构造方法有什么用呢?
用于子类访问父类进行初始化
成员方法:
可以是具体的实现方法,也可也是抽象的方法

        特点:
            1、如果是一个具体的子类,就必须重写所有的抽象方法
            2、如果是一个抽象的子类,可以不重写父抽象类的抽象方法,也可以有选择性的重写
abstract class Animal2{
    int num  = 20;
    final int num2 = 200;

    Animal2(){}

    abstract public void sleep();

}

class Dog extends Animal2{

    @Override
    public void sleep() {
        System.out.println("侧着睡");
    }
}


public class AbstractDemo2 {
    public static void main(String[] args) {
        Animal2 a = new Dog();
        a.sleep();
    }
}

一个类如果没有抽象方法,可不可以定义为抽象类?
可以
如果可以,有什么意义?
如果说一大堆东西,他们都有共同的概念,这个共同的概念本身在现实中是没有具体的存在,把这些概念
集合起来归为一个类,这个类就是抽象类。
至于说这个抽象类有没有方法,却决于这一大堆东西有没有共同的行为,如果说他们只是有着相同的本质。
但是呢,没有共同的行为,这也是合情合理的。

    总结:
        1、抽象类里面可以没有抽象方法
        2、抽象类不能被实例化

    abstract不能和哪些关键字共存
        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();

}

public class AbstractDemo3 {
    public static void main(String[] args) {

    }
}

抽象类练习1:
猫狗案例
具体事物:猫,狗
共性:姓名,年龄,吃饭

    分析:从具体到抽象的过程
        猫:
            成员变量:姓名,年龄
            构造方法:无参构造,有参构造
            成员方法:吃饭(猫吃鱼)

        狗:
            成员变量:姓名,年龄
            构造方法:无参构造,有参构造
            成员方法:吃饭(狗吃肉)

   通过分析发现,猫和狗有一些共性内容,所以我们就根据这些共性内容提取了一个父类:动物类:Animal
   但是呢,又由于吃饭的方式不同,所以吃饭的方法我们定义为抽象方法。
   又因为,吃饭的方法是一个抽象方法,所以该类必须定义为抽象类

   抽象动物类:Animal
        成员变量:姓名,年龄
        构造方法:无参构造,有参构造
        成员方法:吃饭,是一个抽象方法 eat();

   实现:从抽象到具体
        抽象动物类:Animal
           成员变量:name,age;
           构造方法:无参构造,有参构造
           成员方法:吃饭,是一个抽象方法 public abstract void eat();
        狗类:
            继承自动物类
            无参构造,有参构造
            重写抽象的吃饭方法
        猫类:
            继承自动物类
            无参构造,有参构造
            重写抽象的吃饭方法
abstract class Animal3{
    private String name;
    private int age;

    public Animal3() {
    }

    public Animal3(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //是一个抽象方法 public abstract void eat();
    public abstract void eat();
}


class Dog3 extends Animal3{

    public Dog3() {
    }

    public Dog3(String name, int age) {
        super(name, age);
    }

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

class Cat3 extends Animal3{

    public Cat3() {
    }

    public Cat3(String name, int age) {
        super(name, age);
    }

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


public class AbstractTest {
    public static void main(String[] args) {
        Animal3 a = new Cat3("小花",3);
        System.out.println(a.getName()+"---"+a.getAge());
        a.eat();

        Animal3 a2 = new Dog3("大黄",4);
        System.out.println(a2.getName()+"---"+a2.getAge());
        a2.eat();

    }
}

老师案例
具体事物:十三期老师,十二期老师
共性:姓名,年龄,讲课。

    分析:
        十三期老师:
            姓名,年龄
            讲课(讲JavaSE)

        十二期老师:
            姓名,年龄
            讲课(讲Hive)

    实现:
        抽象的老师类:
            姓名,年龄
            讲课,定义为抽象方法
        十三期老师:
            继承自老师类
            姓名,年龄
            讲课(讲JavaSE)
        十二期老师:
            继承自老师类
            姓名,年龄
            讲课(讲Hive)
abstract class Teacher{
    private String name;
    private int age;

    public Teacher() {
    }

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void teach();
}

class ThirteenTeacher extends Teacher{

    public ThirteenTeacher() {
    }

    public ThirteenTeacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("教JavaSE");
    }
}

class TwelveTeacher extends Teacher{

    public TwelveTeacher() {
    }

    public TwelveTeacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void teach() {
        System.out.println("教Hive");
    }
}

public class AbstractTest2 {
    public static void main(String[] args) {
        Teacher t1 = new ThirteenTeacher("小虎",24);
        System.out.println(t1.getName()+"---"+t1.getAge());
        t1.teach();

        Teacher t2 = new TwelveTeacher("火火",24);
        System.out.println(t2.getName()+"---"+t2.getAge());
        t2.teach();
    }
}

学生案例
具体事务:十三期学员,十二期学员
共性:姓名,年龄,班级,学习,吃饭

分析:
    十三期学员:
        姓名,年龄,班级
        学习(学习Java基础),吃饭
    十二期学员:
        姓名,年龄,班级
        学习(学习Hive),吃饭
    抽象的学员:
        姓名,年龄,班级
        学习(定义为抽象方法),吃饭

    实现:
    十三期学员:
        姓名,年龄,班级
        学习(学习Java基础),吃饭
    十二期学员:
        姓名,年龄,班级
        学习(学习Hive),吃饭
    抽象的学员:
        姓名,年龄,班级
        学习(定义为抽象方法),吃饭
abstract class Trainee{
    private String name;
    private int age;
    private String clazz;

    public Trainee() {
    }

    public Trainee(String name, int age, String clazz) {
        this.name = name;
        this.age = age;
        this.clazz = clazz;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    //这是抽象的学习方法
    public abstract void study();

    //具体的吃米饭的方法
    public void eat(){
        System.out.println("吃米饭");
    }
}

class ThirteenTrainee extends Trainee{

    public ThirteenTrainee() {
    }

    public ThirteenTrainee(String name, int age, String clazz) {
        super(name, age, clazz);
    }

    @Override
    public void study() {
        System.out.println("学习Java基础");
    }
}

class TwelveTrainee extends Trainee{

    public TwelveTrainee() {
    }

    public TwelveTrainee(String name, int age, String clazz) {
        super(name, age, clazz);
    }

    @Override
    public void study() {
        System.out.println("学习Hive");
    }
}


public class AbstractTest3 {
    public static void main(String[] args) {
        Trainee t1 = new ThirteenTrainee("陈俊荣",17,"十三期");
        System.out.println(t1.getName()+"---"+t1.getAge()+"---"+t1.getClazz());
        t1.study();
        t1.eat();

        Trainee t2 = new TwelveTrainee("航航",18,"十二期");
        System.out.println(t2.getName()+"---"+t2.getAge()+"---"+t2.getClazz());
        t2.study();
        t2.eat();
    }
}

假如我们在开发一个系统时需要对员工类进行设计,员工包含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();


    }
}

上一篇:Java关键字


下一篇:Photoshop调色教程:靓丽美女色调