面向对象基础-抽象类、接口

本文深入介绍了Java中抽象类和接口的相关知识。阐述了抽象类的概念、特点、成员特点及子类特点,还说明了abstract关键字的使用注意点。同时,引入接口概念,介绍其特点、成员特点、与类的关系及注意事项,指出接口是一种规范,体现‘能够XX’思想。

抽象类

概念与定义

思考:

​ Animal类的继承体系,有什么问题?
从祖先类开始,随着一个个子类的定义,子类变得越来越具体,而祖先类则更具有一般性和抽象性。

​ 在这种情况下,我们将祖先类设计的更加抽象,只将它作为派生其他类的父类,而不能创造实例

​ 这样的类,我们称之为抽象类,使用关键字abstract(抽象的)标记

在这里插入图片描述
但抽象类可以没有抽象方法
在这里插入图片描述

abstract关键字:

​ 修饰类:

​ 1,语法:权限修饰符 abstract class 类名 {}

​ 2,表示该类是一个抽象类

修饰成员方法:

​ 1,语法:权限修饰符 abstract 返回值 方法名 () {} ;

​ 2,该方法是一个抽象方法

抽象类的特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

​ 1,抽象类不能实例化,但是开发中会提供子类,可以用多态的方式访问

​ 2,抽象类具有普通构造方法,成员变量和成员方法

​ 3,抽象类中的构造方法是留给子类初始化时调用的

​ 4,抽象类中可以没有抽象方法

抽象类的成员特点

在这里插入图片描述
结抽象类成员特点:

​ 1,构造方法:同普通类

​ 2,成员变量:同普通类

​ 3,成员方法:可以是抽象方法,也可以是非抽象方法
在这里插入图片描述
在这里插入图片描述

抽象类猫和狗案例

在这里插入图片描述
Animal

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(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();
}

Cat

public class Cat extends Animal {

    public Cat() {
    }

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

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

Dog

public class Dog extends Animal {

    public Dog() {
    }

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

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

AnimalDemo

public class AnimalDemo {
    public static void main(String[] args) {
        //创建对象,按照多态的方式
        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();
        System.out.println("--------");

        a = new Cat("加菲",5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();
    }
}

在这里插入图片描述

抽象类的子类的特点

​ 1,抽象类的子类可以是抽象类也可以是具体类

​ 2,只有当子类重写了所有的继承自抽象类的方法,该子类才能被定义为具体类

​ 3,反之,若任一抽象方法没有被重写,该类都必须定义为抽象类

抽象方法的特点

​ 1,抽象方法没有方法体只有方法声明,不要忘记分号

​ 2,抽象方法必须在一个抽象类中

abstract使用上的注意点

​ 1,不能用来修饰构造器、属性、代码块等结构

​ 2,不能用来修饰final类

​ 3,不能用来修饰私有方法、静态方法 、final方法

​ 4,一个抽象类中可以没有抽象方法,但是意义不是很大

接口

回想Animal继承体系的案例,现在我们把Animal设计成抽象类后

​ 有了新的需求:

​ 现在有一批猫和狗,经过了特殊训练,猫和狗都可以直立行走(Wlak Upright)和骑自行车(Ride Bike)

​ 怎么去描述这群动物?

这群猫狗,抽取出他们共有的特殊技能,然后继承,但是Java并不支持多继承,我们以往的知识已经不能处理这种情况

接口的概念

​ 一方面,我们有时需要从多个类中派生出一个类,继承它们所有的成员,Java语法不适用

​ 另一方面,我们有时候需要从几个类中抽取出共同的行为特征,而它们之间并没有“is-a”关系,继承思想显得不适用

​ 于是我们引入接口这种数据类型

接口概述

​ 1,语法:权限修饰符 interface 接口名 {}

​ 2,接口不是类,而是一种独立的数据类型,和class并列

​ 3,类“继承”接口,称之为实现,使用implements关键字

​ 格式:class 类名 implements 接口名 {}

​ 4,类永远是先继承再实现

接口的特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

接口的成员特点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

​ 1,接口中没有构造器,接口不能实例化

​ 2,接口中的所有成员变量都默认是由public static final修饰的

​ 3,接口中的所有抽象方法都默认是由public abstract修饰的

​ 4,接口与接口之间支持多继承

接口版猫和狗案例

在这里插入图片描述
Jumpping

public interface Jumpping {
    public abstract void jump();
}

Animal

public abstract class Animal { //抽象类
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(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();
}

Cat

public class Cat extends Animal implements Jumpping {

    public Cat() {
    }

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

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

    @Override
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}

AnimalDemo

public class AnimalDemo {
    public static void main(String[] args) {
        //创建对象,调用方法
        Jumpping j = new Cat();
        j.jump();
        System.out.println("--------");

        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();
//        a.jump();//抽象类的多态实现,不能使用接口类中的方法

        a = new Cat("加菲",5);
        System.out.println(a.getName()+","+a.getAge());
        a.eat();
        System.out.println("--------");

        Cat c = new Cat();//具体类的实现
        c.setName("加菲");
        c.setAge(5);
        System.out.println(c.getName()+","+c.getAge());
        c.eat();
        c.jump();
    }
}

在这里插入图片描述

类和接口的关系

在这里插入图片描述
在这里插入图片描述

接口和类的区别

在这里插入图片描述
在这里插入图片描述
改进
在这里插入图片描述

​ a,从定义上:

​ 类是一组数据集合(属性)和基于这个数据集合的一组操作(行为)类描述的是对象的共性特征,包括属性和行为

​ 接口只是行为和常量属性的集合

​ b,从行为的关系上:

​ 类中的行为都是有直接间接关系的,都可以访问同一个数据集合

​ 接口中的行为,往往没啥关系

接口的注意事项

​ 1,定义Java类的语法格式:先写extends,后写implements

​ class SubClass extends SuperClass implements InterfaceA{ }

​ 2,一个类可以实现多个接口,接口也可以继承其它接口,这就是Java当中的“多继承”

​ 3,实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。

​ 4,接口的主要用途就是被实现类实现

​ 5,与继承关系类似,接口与实现类之间存在多态性

​ 6,接口和类是并列关系

Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。

**静态方法:**使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行

其方法体。

**默认方法:**默认方法使用 default 关键字修饰。可以通过实现类对象来调用。

编号区别点抽象类接口
1定义包含抽象方法的类抽象方法和全局常量的集合
2组成构造方法、抽象方法、普通方法、常量、变量常量、抽象方法、(jdk8:默认方法、静态方法)
3使用子类继承抽象类(extends)子类实现接口(implements)
4关系抽象类可以实现多个接口接口不能继承抽象类,但允许继承多个接口
5对象不能创建对象,但是有构造方法不能创建对象,也没有构造方法
6局限抽象类不能被多继承接口之间能多继承,能被多实现
7思想作为模板或对共性抽象,is-a作为标准或对共性能力抽象,like-a
8选择如果抽象类和接口都可以使用的话,优先使用接口,因为避免单继承的局限

​ 接口就是这样的一种规范,它抽取了事物的相似行为,而不关心事物有什么关系

​ 1,相比于继承抽象类的“is-a”关系,体现的是“是XX”思想,而实现接口体现的是“能够XX”的思想

​ 2,接口允许多实现。实现多个接口,继承它们所有的属性和方法

​ 3,接口的本质是契约、规范、标准

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值