抽象类、接口、抽象类和接口的比较

目录

抽象类

抽象类 vS 普通类 的成员特点:

练习

接口

接口的语法

接口的特点

抽象类和接口的比较

练习


抽象类

包含  有抽象方法的类  或  被abstract修饰的类

引入抽象类会有一个强制约束力,子类方法必须覆盖

抽象类和抽象方法必须用abstract关键字修饰
    abstract class 类名{ }   //不能 new 类名
    public abstract void eat();  //没有方法体
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
抽象类不能直接实例化(创建对象)
抽象类的子类可以是抽象类,也可以是具体类  

间接实例化:抽象类类型 引用 = new 具体子类();

package com.wolf.basic;

public class Demo1 {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();
    }
}

/*为了实现多态,不然编译看左面就没有方法*/
abstract class Animal {
    public abstract void eat();
}

/*抽象类的子类是具体类*/
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("鱼");
    }

    public void sleep() {
        System.out.println("睡了");
    }
}

/*抽象类的子类是抽象类*/
abstract class MamalAnimal extends Animal {
    //哺乳动物还是包含许多动物,还是没有具体实现
}

/*抽象类不一定有抽象方法*/
abstract class A {
    public void Test() {
    }
}

抽象类 vS 普通类 的成员特点:

构造方法:抽象类同普通类(不能实例化,为啥有构造方法?)
成员变量:抽象类同普通类
成员方法:
    抽象类:
        可以是抽象方法:类中有这样的行为,但不知如何实现
        也可以是非抽象方法:主要实现代码复用
    普通类:非抽象方法
    
不能实例化,为啥有构造方法?
    1.因为抽象类中,可以像普通类一样,定义成员变量,而这些成员变量,在创建子类对象的时候,也是初始化
    2.在子类对象当中,抽象父类中定义的成员,它们值的初始化,交给抽象父类的构造方法来完成(各司其职)

package com.wolf.basic;

/**
 * @create 2021-07-25 18:59
 * 不能实例化,为啥有构造方法?
 */
public class Demo2 {
}

abstract class Father {
    int fatherI;

    public Father(int fatherI) {
        this.fatherI = fatherI;
    }
}

class Son extends Father {
    int sonI;

    public Son(int fatherI, int sonI) {
        super(fatherI);
        this.sonI = sonI;
    }
}

练习

假如我们在开发一个系统时需要对员工类进行设计:
1.员工包含3个属性:姓名、工号以及工资。
2.经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
3.经理和员工,他们都有共同的行为,即工作,但是他们具体的工作内容背定不一样

请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。

package com.wolf.basic;

/**
 * @create 2021-07-25 19:32
 */
public class Exercise {
    public static void main(String[] args) {
        Employee employee = new Employee("张三", 1, 100);
        System.out.println(employee.getName() + " " + employee.getWorkId() + " " + employee.getSalary());
        employee.work();
        Manager manager = new Manager("Lisi", 2, 300, 100);
        System.out.println(manager.getName() + " " + manager.getWorkId() + " " + manager.getSalary());
        manager.work();
    }
}

abstract class BaseEmployee {
    private String name;
    private int workId;
    private double salary;

    public BaseEmployee(String name, int workId, double salary) {
        this.name = name;
        this.workId = workId;
        this.salary = salary;
    }

    //员工、经理都要工作,但内容不同
    public abstract void work();

    public String getName() {
        return name;
    }

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

    public int getWorkId() {
        return workId;
    }

    public void setWorkId(int workId) {
        this.workId = workId;
    }

    public double getSalary() {
        return salary;
    }

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

/*员工类*/
class Employee extends BaseEmployee {
    public Employee(String name, int workId, double salary) {
        super(name, workId, salary);
    }

    @Override
    public void work() {
        System.out.println("员工工作");
    }
}

/*经理类*/
class Manager extends BaseEmployee {
    public Manager(String name, int workId, double salary, double bonus) {
        super(name, workId, salary);
        this.bonus = bonus;
    }

    private double bonus;

    @Override
    public void work() {
        System.out.println("经理工作");
    }

    public double getBonus() {
        return bonus;
    }

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

    @Override
    public double getSalary() {
        return super.getSalary() + bonus;
    }
}

1.抽象类中,可以不包含抽象方法,一个不包含抽象发发的抽象类的意义
    虽不包含抽象方法,但无法直接new,对于绝大部分普通场景可以直接使用,可能在某些场景不能使用,让别人继承使用,写注释提示别人哪些场景适用(理论上)

2.abstract不能和哪些关键字共存
    private 不可以
    final 不可以
    static 不可以

对于冲突的理解:对于抽象方法,要在代码中使用,必须依赖多态,调用子类中覆盖实现抽象父类的抽象方法,而被private、final、static关键字修饰的方法,都不能在子类中被覆盖


接口

不同动物的相同行为 放在一起 如果有的猫和狗可以跳或者计算,有的却不可以

package com.wolf.introduction;

/**
 * @create 2021-07-25 20:53
 */

public class Demo1 {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();
    }
}


abstract class Animal {
    public abstract void eat();

    public abstract void shout();
}


class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("鱼");
    }

    @Override
    public void shout() {
        System.out.println("喵喵喵");
    }

    public void sleep() {
        System.out.println("睡了");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("骨头");
    }

    @Override
    public void shout() {
        System.out.println("汪汪汪");
    }
}

//此时可能会想到
abstract class SpecialAnimal {
    public abstract void jump();//某些可以跳

    public abstract void calculate();//某些可以计算
} 
//类的单重继承不可以这么做,故引入接口
//class SpecialCat extends SpecialAnimal,Cat{}
interface SpecialAnimal {
    public abstract void jump();//某些可以跳

    public abstract void calculate();//某些可以计算
}

接口的语法

(接口是纯粹的抽象,抽象类可以都是普通类)
1.接口用关键字interface表示
    格式: interface 接口名 { }

2.在Java语言中Interface也可以表示一种数据类型
    a.类和接口都可以用来表示数据类型(类和接口是地位对等的),只不过他们的侧重点不一样
    操作(行为)描述:
    b.类定义的是一个数据集合  基于这个数据集的一组操作(行为),类所描述的这一组行为,它们是有关系的(间接),都可以访问同一个数据集合
    c.接口表示数据类型,侧重于描述,一组具有特殊功能的行为,这些行为,可以完全没有任何关系。
        接口中的方法,它们的关系比较的松散

3.类实现接口用implements表示
    类和接口可以有实现关系(也可以说是继承关系),用implements表示
    格式: class 类名 implements 接口名 {}

4.接口不能直接实例化(只能有抽象方法,jdk8及以后不是)

5.接口的子类:
    a.可以是抽象类
    b.也可以是具体类

public class Demo1 {
    public static void main(String[] args) {
        //接口的间接实例化
        InterfaceClass interfaceClass = new InterfaceClass();
    }
}
//定义一个接口
interface MyInterface{
    public abstract void show();
}
//实现接口
class InterfaceClass implements MyInterface{

    @Override
    public void show() {
        System.out.println("实例化");
    }
}

接口的特点

无构造方法 成员变量:只能是常量,默认修饰符 public static final 成员方法:只能是抽象方法,默认修饰符 public abstract

回顾一下,之前我们讲类的时候说过,Java中类与类之间只能单重继承。那么是不是Java中,只有单重继承呢? 不是

之所以,java声称自己实现了多重继承
1.接口 与 接口 之间可以实现多重继承
2.一个类可以在继承其他类的情况下,同时实现多个接口

一个考虑接口的比较完整的类定义语法
class 类名 extends 其他类类名 implements接口1,接口2... { }

public class Demo3 {
}

interface FirstInterface {
    void firstMethod();
}

interface SecondInterface {
    void secondMethod();
}

interface ThirdInterface extends FirstInterface, SecondInterface {
}

class TestInterfaceExtend implements ThirdInterface {

    @Override
    public void firstMethod() {

    }

    @Override
    public void secondMethod() {

    }
}

interface FourthInterface {
    void forthMethod();
}

interface FiveInterface {
    void fiveMethod();
}

class CompleteClass extends TestInterfaceExtend implements FourthInterface, FiveInterface {

    @Override
    public void forthMethod() {

    }

    @Override
    public void fiveMethod() {

    }
}

抽象类和接口的比较

成员区别
    抽象类   变量;有抽象方法;非抽象方法
    接口      常量;抽象方法

关系区别
    类与类继承,单继承
    类与接口实现,单实现,多实现
    接口与接口继承,单继承,多继承

设计理念区别
    抽象类 被继承体现的是: "is a”的关系。共性功能
    接口 被实现体现的是: ”like a”的关系。扩展功能

/*
		接上
*/
interface SpecialSkills {
    public abstract void jump();//某些可以跳

    public abstract void calculate();//某些可以计算
}
class SpecialCat extends Cat implements SpecialSkills{

    @Override
    public void jump() {
        System.out.println("cat jump");
    }

    @Override
    public void calculate() {
        System.out.println("cat calculate");
    }
}
class SpecialDog extends Dog implements SpecialSkills{

    @Override
    public void jump() {
        System.out.println("dog jump");
    }

    @Override
    public void calculate() {
        System.out.println("dog calculate");
    }
}

练习

教练和运动员案例
乒乓球运动员和篮球运动员。乒乓球教练和篮球教练。
为了出国交流,跟乒乓球相关的人员都需要学习英语。
请用所学知识:分析,这个案例中有哪些抽象类,哪些接口,哪些具体类。

乒乓球运动员
丽性: name,age,salary
行为: eat() , sleep(), train() , match()
乒乓球教练
属性: name,age,salary,bonus
行为: eat(), sleep() , teach()
足球运动员
属性: name,age,salary
行为: eat(), sleep(), train() , match()
足球教练
属性: name,age,salary, bonus
行为: eat() , sleep(), teach()

从共性:
1.所有的运动员和教练员  定义一个所有运动员和教练员都要继承公共父类 Human 普通
    有相同的属性: name,age,salary
    有相同的行为: eat() , sleep()

2.定义类来描述运动员和教练员
    a.教练员和运动员 继承 Human
    b.对于教练员而言:定义一个类 Coach 抽象类 extend Human
        多了一个属性 bonus
        多了一个行为:teach(),同时注意到不同类型的教练员,teach的内容不一样,抽象方法
    c.对于运动员而言:定义一个类 Athlete 抽象类 extends Human
        多了运动员特有的行为: train() , match()
        但是,不同类型的有动员,但是训练和比赛的内容是不一样,train(),match()抽象方法

3.分别定义
    乒乓球运动员:TableTennisAthlete extends Athlete,继承之后,事项 train(),match()
    乒乓球教练:TableTennisCoach extends Coach,继承只需要实现 teach()
    足球运动员:FootballAthlete extends Athlete,继承之后,事项 train(), match()
    足球教练:FootballCoach extends Coach,继承只需要实现 teach()

4.功能扩展
    implements SpecialSkills{ }

package com.wolf.introduction;

/**
 * @create 2021-07-26 16:35
 */
public class Exercise {
    public static void main(String[] args) {
        TableTennisAthlete tableTennisAthlete = new TableTennisAthlete("张三", 20, 1000);
        tableTennisAthlete.learnEnglish();
        tableTennisAthlete.match();
        tableTennisAthlete.train();
        tableTennisAthlete.eat();
        tableTennisAthlete.sleep();
        tableTennisAthlete.setSalary(2000);
        System.out.println(tableTennisAthlete.getName() + " " + tableTennisAthlete.getSalary() + " " + tableTennisAthlete.getAge());
        System.out.println("--------------------------------");
        TableTennisCoach tableTennisCoach = new TableTennisCoach("lisi", 30, 10000, 5000);
        tableTennisCoach.learnEnglish();
        tableTennisCoach.teach();
        tableTennisCoach.setBonus(1000);
        System.out.println(tableTennisCoach.getName() + " " + tableTennisCoach.getSalary());
        tableTennisCoach.sleep();
    }
}

class Human {
    private String name;
    private int age;
    private int salary;

    public void eat() {
        System.out.println(name + "吃");
    }

    public void sleep() {
        System.out.println(name + "睡");
    }

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

    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 int getSalary() {
        return salary;
    }

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

abstract class Coach extends Human {
    private int bonus;

    public abstract void teach();

    public Coach(String name, int age, int salary, int bonus) {
        super(name, age, salary);
        this.bonus = bonus;
    }

    public int getBonus() {
        return bonus;
    }

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

    @Override
    public int getSalary() {
        return super.getSalary() + bonus;
    }
}

abstract class Athlete extends Human {
    public Athlete(String name, int age, int salary) {
        super(name, age, salary);
    }

    public abstract void train();

    public abstract void match();
}

interface SpecialSkills {
    void learnEnglish();
}

class TableTennisAthlete extends Athlete implements SpecialSkills {

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

    @Override
    public void train() {
        System.out.println("乒乓球运动员:" + super.getName() + "训练");
    }

    @Override
    public void match() {
        System.out.println("乒乓球运动员:" + super.getName() + "比赛");
    }

    @Override
    public void learnEnglish() {
        System.out.println("乒乓球运动员:" + super.getName() + "学英语");
    }
}

class TableTennisCoach extends Coach implements SpecialSkills {

    public TableTennisCoach(String name, int age, int salary, int bonus) {
        super(name, age, salary, bonus);
    }

    @Override
    public void teach() {
        System.out.println("乒乓球教练:" + super.getName() + "教课");
    }

    @Override
    public void learnEnglish() {
        System.out.println("乒乓球教练:" + super.getName() + "学习英语");
    }
}

class FootballAthlete extends Athlete {

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

    @Override
    public void train() {
        System.out.println("足球运动员:" + super.getName() + "训练");
    }

    @Override
    public void match() {
        System.out.println("足球运动员:" + super.getName() + "比赛");
    }

}

class FootballCoach extends Coach {

    public FootballCoach(String name, int age, int salary, int bonus) {
        super(name, age, salary, bonus);
    }

    @Override
    public void teach() {
        System.out.println("足球教练:" + super.getName() + "教课");
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值