Java 抽象类 和 接口

首先在了解抽象类和接口之前,我们需要知道什么是继承?什么是重写?

而在知道抽象类和接口之后,我们就需要知道什么是多态?

(主要是了解怎样用抽象类和接口去实现多态)

目录

1.继承

2.重写

3.抽象类

4.接口

5.多态


进入正题:

1.继承

我们都知道 Java 是一门面向对象编程的语言,而对象说穿了就是 Java 中的 类(class)。

那继承是什么呢?

举个例子:

我先创建一个 Dog 类,其中有 name ,leg 属性字段,同时还有一个 cry 方法和一个eat方法。

在创一个Bird类,其中也有name,wing属性字段,同时还有一个 fly 方法和一个 eat 方法。

//这便是我们平常所创建的类
public class Dog {
    public String name;   //名字
    public String leg;    //几条腿

    public void cry(){
        System.out.println(this.name+"汪汪叫!");
    }
    public void eat(){
        System.out.println(this.name+"吃东西");
    }
}


public class Bird {
    public String name;   //名字
    public String wing;   //翅膀

    public void fly(){
        System.out.println(this.name+"会飞");
    }
    public void eat(){
        System.out.println(this.name+"吃东西");
    }
}

通过观察上面这两个类,我们可以发现它们有共同的属性和方法。可以想象一下,如果我们需要许多的类,恰巧这些类中有许多重复的代码,那么就会浪费我们大量的时间。

所以 继承 便出来了。

将上面的代码使用继承进行处理:

//Dog 子类继承于 Animal 父类
public class Dog extends Animal{
    public String leg;    //几条腿
    public Dog(String name){
        super(name);
    }
    public void cry(){
        System.out.println(this.name+"汪汪叫!");
    }
}

//Bird 子类继承于 Animal 父类
public class Bird extends Animal{
    public String wing;   //翅膀
    public Bird(String name) {
        super(name);
    }
    public void fly(){
        System.out.println(this.name+"会飞");
    }
}

//父类
public class Animal {
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(){
        System.out.println(name+"吃东西");
    }
}

在上面的代码中,我们将 Dog 类 和 Bird 类中的重复性的属性和方法,都放到了一个单独的 Animal 类中,然后让 Dog 类和 Bird 类使用 extends 关键字继承 Animal 类。

这时,我们就称 Dog 类和 Bird 类为子类(或者叫派生类)

Animal 类称父类(或者叫基类,超类)

那么怎么使用父类的属性和方法呢?

//建一个测试用的类
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小白");
        System.out.println(dog.name);
        dog.eat();

        Bird bird = new Bird("小黄");
        System.out.println(bird.name);
        bird.fly();
    }
}

运行结果:

 说明子类能够调用父类的方法和属性。

2.重写

通过上面的代码,我们可以发现子类可以调用所继承的父类的方法和属性。

但是如果父类的方法,在子类中也有呢?

这时调用该方法,运行的是子类的方法还是父类的方法?

下面来尝试一下:
 

//我们在Dog类和Bird类中都写上它们的eat方法
public class Dog extends Animal{
    public String leg;    //几条腿
    public Dog(String name){
        super(name);
    }
    public void cry(){
        System.out.println(this.name+"汪汪叫!");
    }
    public void eat(){
        System.out.println("我是子类Dog的eat方法!");
    }
}

public class Bird extends Animal{
    public String wing;   //翅膀
    public Bird(String name) {
        super(name);
    }
    public void fly(){
        System.out.println(this.name+"会飞");
    }
    public void eat(){
        System.out.println("我是子类Bird的eat方法!");
    }
}

//父类的eat方法不变
public class Animal {
    public String name;
    public Animal(String name) {
        this.name = name;
    }
    public void eat(){
        System.out.println(name+"吃东西");
    }
}

然后调用测试类:

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog("小白");
        System.out.println(dog.name);
        dog.eat();

        Bird bird = new Bird("小黄");
        System.out.println(bird.name);
        bird.eat();
    }
}

运行结果:

说明只要子类和父类有相同的方法(返回类型相同,方法名相同,参数列表相同),子类调用该方法时,就会调用子类自己的方法。

我们称这一现象为:重写,就是说子类重写了父类的方法。

3.抽象类

在上面的例子中,Animal 这个父类里面拥有子类Dog和Bird共同的方法和属性。并且Animal这个父类唯一的作用就是被子类继承。

所以在Java中专门为这种类起了个名字,并且用一个关键字修饰 (abstract)——抽象类

抽象类不能被实例化,只能被别的实体类所继承。

抽象类中除了拥有普通的方法和属性,还拥有抽象方法,同样是使用 abstract 修饰。

那么什么是抽象方法呢?

用例子更好理解:

//这是一个abstract关键字修饰的抽象类
public abstract class Animal {
    public String name;  //普通成员变量
    public Animal(String name) { //构造方法
        this.name = name;
    }
    public void run(){  //普通方法
        System.out.println("跑起来");
    }
    //这是一个被abstract关键字修饰的抽象方法,它没有身体,必须被子类重写。
    public abstract void eat();
}

同时需要注意,有抽象方法的类一定是抽象类,而抽象类不一定有抽象方法。

4.接口

在上面我们知道了什么是抽象类,那么接口就很好理解了。

接口就是一种特殊的抽象类,为什么特殊?

因为如果一个类是接口,那么它一定是抽象类,反之一个类是抽象类,那么它不一定是接口。

(一个接口需要用关键字 interface 来修饰)

下面还是用Animal这个类来举例:

//这是一个interface关键字修饰的接口
public interface Animal {
    //public static final 修饰的属性常量。
    public static final String name = "小黄";
    int age = 20; //在接口中无论你写不写,属性默认都是public static final修饰

    //接口中只能有抽象方法,实体类实现这个接口后,必须要重写这个抽象方法
    public abstract void eat();

    //或者default修饰的方法,实体类可以不用重写这个方法
    default void run(){

    }
    //或者是静态方法
    public static void cry(){
        System.out.println("叫声");
    }
}

 当我们知道了接口怎么定义后,就会想它到底能干嘛?

我们知道在Java中一个实体类,只能 继承 一个父类。所以有时候我们就会发现一个事物的父类有很多。所以为了解决这个问题,Java中就引入了一个概念——接口。

这里要说一下类之间的关系:

实体类与抽象类之间是继承关系。

实体类与接口之间是实现关系。

接口与接口之间也是继承关系。

这样的话,一个实体类就可以继承一个抽象类,并实现多个接口。从而满足它所需要的方法和属性

5.多态

概念性的讲,就是 “一个引用, 能表现出多种不同形态”

通过举例能更好的理解:

//定义一个图形的父类
abstract class Shape{
    public abstract void print();  //这是一个需要被重写的抽象方法
}

//三角形
class Triangle extends Shape{
    //重写父类的print方法
    @Override
    public void print() {
        System.out.println("△");
    }
}

//矩形
class Rectangle extends Shape{
    //重写父类print方法
    @Override
    public void print() {
        System.out.println("□");
    }
}

//圆圈
class Circle extends Shape{
    //重写父类print方法
    @Override
    public void print() {
        System.out.println("○");
    }
}

//使用多态需要满足两个条件
//1.向上转型:父类引用 引用 子类对象
//         例如 Shape x = new Triangle();
//2.重写父类方法。
public class Test {
    public static void draw(Shape x){   //这里是用父类对象的引用接收
        x.print();
    }
    public static void main(String[] args) {
        Triangle triangle = new Triangle();
        Rectangle rectangle = new Rectangle();
        Circle circle = new Circle();

        //调用draw方法,就发生了多态
        draw(triangle);   //传过去的是子类对象的引用
        draw(rectangle);
        draw(circle);

    }
}

运行结果:

有时候理解一个概念,往往不需要用很复杂的例子,相反越简单,越通俗易懂。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值