抽象类和接口

荒凉一梦 提交于 2020-02-27 08:41:17

抽象类

在Java中,你可以只给出方法的定义不去实现方法的具体事物,由子类去根据具体需求来具体实现。这种只给出方法定义而不具体实现的方法被称为抽象方法,包含一个或多个抽象方法的类称为抽象类
举个例子来说:一个图形类应该有面积的方法,但是不同的图形求面积方法不一样。分析事物,发现共性,就出现了向上抽取。
方法的声名相同,但是方法功能主体不同,这样就可以抽取,但只是抽取方法声名,但不抽取方法主体,称这个方法就是抽象方法。

  • 方法前加上 abstract 关键字, 表示这是一个抽象方法,抽象方法是没有方法体的,在代码的表达上就是没有“{}”。
  • 包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.
//有抽象方法的类也必须被声明为abstract
abstract class Shape {
	//抽象方法,不能有“{}”
	abstract public void draw();
}
  • 抽象类不能直接实例化.
  • 抽象方法不能是 private 的
  • 抽象类中可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,也可以被子类直接调用
//抽象类
abstract class People{
    //抽象方法
    public abstract void work();
}
class Doctor extends People{
    private String work;
    public Doctor(String work) {
        this.work=work;
    }
    //重写方法
    @Override
    public void work() {
        System.out.println("我的职业是"+this.work);
    }

}
class Lawyer extends People {
    private String work;

    public Lawyer(String work) {
        this.work = work;
    }

    @Override
    public void work() {
        System.out.println("我的职业是" + this.work);
    }
}
public class Solution {
    public static void main(String[] args) {
        Doctor doctor=new Doctor("医生");
        doctor.work();

        Lawyer lawyer=new Lawyer("律师");
        lawyer.work();
    }
}

在这里插入图片描述

抽象类的作用:

抽象类存在的最大意义就是为了被继承.抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法。使用抽象类相当于多了一重编译器的校验.

接口

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能).

接口的特点:

1、Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被显示初始化,即接口中的成员变量为常量(大写,单词之间用"_"分隔)

2、Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化

3、Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法

4、接口中没有构造方法,不能被实例化

5、一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口

6、Java接口必须通过类来实现它的抽象方法

7、当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类

8、不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例

9、一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承.

实现多个接口

有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.
然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果.

现在我们通过类来表示一组动物。

class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
}
//提供一组接口, 分别表示 "会飞的", "会跑的", "会游泳的"
interface IFlying {
    void fly();
}
interface IRunning {
    void run();
}
interface ISwimming {
    void swim();
}
//创建几个具体的动物
//猫跑
class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用四条腿跑");
    }
}
//鱼游
class Fish extends Animal implements ISwimming {
    public Fish(String name) {
        super(name);
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在用尾巴游泳");
    }
}
//青蛙跑和游
class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在往前跳");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游泳");
    }
}
//鸭子跑、飞、游
class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }
    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飞");
    }
    @Override
    public void run() {
        System.out.println(this.name + "正在用两条腿跑");
    }
    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}
public class Solution {
    public static void main(String[] args) {
        Cat cat = new Cat("小猫");
        cat.run();
        Fish fish = new Fish("小鱼");
        fish.swim();
        Frog frog = new Frog("青蛙");
        frog.run();
        frog.swim();
        Duck duck = new Duck("鸭子");
        duck.run();
        duck.swim();
        duck.fly();
    }
}

在这里插入图片描述
时刻牢记多态的好处, 忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力。

接口间的继承

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.

interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}

通过接口继承创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法,
也需要实现 swim 方法。

抽象类和接口的区别

区别 抽象类(abstract) 接口(interface)
结构组成 普通类+抽象方法 抽象方法+全局常量
权限 public 各种权限
子类使用 使用extends关键字继承抽象类 使用implements关键字实现接口
关系 一个抽象类可以实现多个接口 接口不能继承抽象类,但接口可以使用extends关键字继承多个父接口
子类限制 一个子类只能继承一个抽象类 一个子类可以实现多个接口
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!