JavaSE笔记13 抽象类+接口

本文详细探讨了Java中的抽象类和接口,包括它们的定义、特点、成员特点以及类与接口之间的关系。抽象类主要用于抽象出子类的共性功能,而接口则提供了一种定义扩展功能的方式,允许类实现多个接口以获得多种功能。此外,文章还阐述了抽象类和接口的区别以及在实际编程中的应用示例。
摘要由CSDN通过智能技术生成

JavaSE笔记13 抽象类+接口

Part1.抽象类:

一.抽象类和抽象方法的概述:

在继承关系中,我们将子类中的共性功能向上抽取到父类,并且对这些共性功能在父类中给出了具体的实现。但是实际上父类并不知道子类对于共性功能的具体实现,所以可以将共性功能抽象出来,具体的实现细节由子类自身的差异性,去具体实现
即:父类只需要给出共性功能的声明即可,也就是把共性功能定义为抽象的
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类

对于抽象类和抽象方法的定义格式:
抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();

二.抽象类和抽象方法的特点:

抽象类与抽象方法的注意事项
一旦类中有了抽象方法,此类必须定义为一个抽象类
一个抽象类中,可以没有抽象方法,当然也可以有非抽象方法
抽象类中可以有抽象方法,也可以有非抽象的方法。非抽象方法,可以让子类进行继承使用;抽象方法强制子类必须进行重写
抽象类中存在构造方法,作用是:创建子类时,先初始化父类的数据
抽象类不能直接创建其对象,可以直接采取多态的方式,间接进行实例化
作为抽象类的子类,必须重写父类中所有的抽象方法;当然也可以不重写父类中的抽象方法,将自己定义为抽象类即可
言外之意:抽象类的子类,要么是抽象类,要么重写抽象类中的所有抽象方法

代码演示抽象类和抽象方法:

public class MyTest {
    public static void main(String[] args) {
        /*1.一个类中有了抽象方法,此类也必须定义为抽象类
          2.抽象类中可以有抽象方法,可以有非抽象方法
          3.非抽象方法可以让子类继承使用,抽象方法要强制
          子类必须进行重写
          4.抽象类中存在构造方法,作用是:创建子类时,
          先初始化父类的数据
          5.抽象类不能直接创建其对象,可以采取多态的形式
          进行实例化
         */
        Fu fu = new Zi();
        //多态形式访问成员变量,编译看父类,运行看父类
        System.out.println(fu.num);//50
        //多态访问成员方法,成员方法有重写,编译看父类,运行看子类
        fu.show();
    }
}

//父类,抽象类
abstract  class Fu{
    //父类的空参构造
    public Fu(){
        System.out.println("父类构造执行了");
    }
    //父类的成员变量
    int num=50;
    //抽象方法
    public abstract void show();
}

class Zi extends Fu{
    //子类的构造方法
    public Zi(){
        System.out.println("子类构造执行了");
    }
    //子类的成员变量
    int num=200;
    //子类重写父类中的成员方法
    @Override
    public void show() {
        System.out.println("子类重写父类的show方法");
    }
}

在这里插入图片描述

/*作为抽象类的子类,必须重写子类中的抽象方法,
或者将子类自己定义为一个抽象类
 */
public abstract class CC {
    public abstract void cc();
    public abstract void cc1();
    public abstract void cc2();
}
//方式一:重写父类CC中的所有抽象的方法
class DD extends CC{
    @Override
    public void cc() {

    }

    @Override
    public void cc1() {

    }

    @Override
    public void cc2() {

    }
}
//方式二:将子类ee也定义为抽象类,将父类中抽象方法继承使用
abstract  class EE extends CC{
    
}

三.抽象类的成员特点:

抽象类的成员特点:

  • 成员变量: 既可以是变量,也可以是常量
  • 构造方法: 有,用于子类访问父类数据的初始化
  • 成员方法: 既可以是抽象的,也可以是非抽象的

抽象类的成员方法特性:

  • 抽象方法: 强制要求子类做的事情。
  • 非抽象方法: 子类继承的事情,提高代码复用性

代码演示:
主测试类:

public class MyTest {
    public static final int num = 100;

    public static void main(String[] args) {
        Person person = new Student();
        person.name = "zjl";
        person.age = 18;
        System.out.println(person.name);
        System.out.println(person.age);
        person.eat();
        person.sleep();
        Student student = (Student) person;
        student.talkLove();
        System.out.println("=============================================================");
        person = new Teacher();
        person.name = "java沈";
        person.age = 36;
        System.out.println(person.name);
        System.out.println(person.age);
        person.eat();
        person.sleep();
        Teacher t = (Teacher) person;
        t.teach();


        //	一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
        //答案: 可以 . 不能创建对象.
        W.hehe();
        WW.hehe();

        //abstract不能和哪些关键字共存?
        // private abstract 矛盾,private abstract
        // final abstract 矛盾
        // static abstract 没有意义,静态方法,不算重写
    }
}


class WW {
    private WW() {
    }

    public static void hehe() {

    }
}

abstract class W {
    public static void hehe() {

    }

    //private abstract void haha();

    //  public final abstract void hehe();

    //   public static abstract void hh();
}

Person类:

public abstract class Person {
    public String name;
    public int age;

    public abstract void eat();

    public abstract void sleep();
}

Student类:

public class Student extends Person {

    @Override
    public void eat() {
        System.out.println("学生爱吃麻辣烫");
    }

    @Override
    public void sleep() {
        System.out.println("学生晚上狂欢,白天睡觉");
    }


    public void talkLove() {
        System.out.println("学生谈恋爱");
    }
}

Teacher类:

public class Teacher extends Person {

    @Override
    public void eat() {
        System.out.println("老师爱吃 燃面");
    }

    @Override
    public void sleep() {
        System.out.println("老师晚上搂着媳妇睡觉");
    }

    public void teach() {
        System.out.println("老师教书");
    }
}

运行结果:
在这里插入图片描述

四.抽象类与抽象方法的简答题:

1.一个类中如果没有抽象方法,可不可以定义为抽象类?如果可以,有何意义?
抽象类中可以有抽象方法,可以有非抽象方法。非抽象方法可以继承让子类进行使用,抽象方法要求子类必须进行重写。一个类中如果没有抽象方法,可以定义为抽象类。外界不能直接创建该抽象类的对象。
2.abstract关键字不能与哪些关键字进行共存?

  • abstrct不能与fianl关键字进行共存:abstract强制子类重写方法,final修饰的方法不能被子类进行重写
  • abstract不能与private关键字进行共存:private修饰的方法无法继承,也无法进行重写
  • abstract不能与static关键字共存:静态方法不参与重写,abstract修饰的方法要求子类进行重写

Part2.接口:

一.接口的概述:

我们知道java中只支持单继承,但如果我们想定义一些功能,想让一个子类都继承实现,显然没办法做到,所有Java提供了接口这个概念。这样我们就可以用一个子类去实现多个接口。我们可以理解为接口就是特殊的抽象类
为了体现事物的扩展性,Java中就提供了接口去定义这些额外的功能,并不给出具体的是实现。将来哪些类需要需要继承这些功能,只需要实现接口就行

二.接口的特点:

接口用关键字interface表示
格式: interface 接口名 {}

类实现接口用implements表示
格式: class 类名 implements 接口名 {}

注意事项:

  • 接口不能直接实例化:接口的实例化方式是按照多态的方式来实例化
  • 接口的子类:
    [1] 可以是抽象类。但是意义不大
    [2] 可以是具体类。要重写接口中的所有抽象方法(推荐方案)

代码演示:

public class MyTest {
    public static void main(String[] args) {
        //接口不能直接创建对象
        //子类和接口之间的关系是实现关系,implements
        //可以将子类与接口之间的关系称为:父接口,子类
        MyInterface myInterface=new Cat();
        myInterface.jump();
    }
}

/*interface定义一个接口,接口中定义的都是一些扩展的功能
  哪类事物想要具备该扩展功能,需要实现该接口*/
interface  MyInterface{
    //接口中定义了扩展的功能:跳高
    public abstract void jump();
}

//抽象类
abstract class Animal{
    //抽象方法
    public abstract void eat();
    public abstract void sleep();
}

//类与接口的关系是实现的关系
//接口中的抽象方法,实现的类必须对方法重写
class Cat extends Animal implements MyInterface{
    @Override
    public void eat() {
        System.out.println("小猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("小猫喜欢在温暖的地方睡觉");
    }

    @Override
    public void jump() {
        System.out.println("小猫经过学习学会了跳高");
    }
}

在这里插入图片描述

三.接口中的成员特点:

  • 成员变量;只能是常量,并且是静态的
    默认修饰符:public static final
    建议:自己手动给出
  • 构造方法:接口没有构造方法
  • 成员方法:只能是抽象方法
    默认修饰符:public abstract
    建议:自己手动给出

代码演示:

public class MyTest {
    public static void main(String[] args) {
        //接口中的公共静态常量,可以直接通过接口名直接调用
        System.out.println(MyInterface.num);

    }
}
/*接口:interface它主要定义一些扩展的功能,将来
  哪些事物想要具备这些扩展功能,就可以实现这个接口
  接口,其实用来定义一些规范,对于这些规范的实现,
  肯定由子类来进行具体的实现
 */
interface MyInterface{
    //接口中的成员变量默认为公共的静态常量
    //成员变量前存在public static final的修饰符
  public static final  int num=30;
    //接口中的方法全部都是抽象方法
    //方法前存在默认public abstract修饰符
  public abstract void aa();
}

在这里插入图片描述

四.类,接口的关系:

类,接口的关系总述
类与类之间的关系:类与类之间形成继承关系,并且只能是单继承,可以多层继承
类与接口之间的关系:类与接口之间的关系是实现的关系,并且可以多实现(也就是说一个类可以实现多个接口)
接口与接口之间的关系:接口与接口关系是继承关系,并且可以多继承
1.类和类之间的关系:

类与类之间的关系:类与类之间形成继承关系,并且只能是单继承,可以多层继承
代码演示:

public class MyTest1 {
    public static void main(String[] args) {
        //多态:父类的引用指向子类的对象
        Fu fu = new Zi();
        //多态访问成员变量,编译看父类,运行看父类
        System.out.println(fu.num);
        fu.show();
        //想要访问子类中特有的成员需要向下转型
        Zi zi= (Zi) fu;
        System.out.println(zi.num);
    }

}
//父类
class Fu{
    //父类的成员变量
    int num=30;
    public void show(){
        System.out.println("父类的show方法");
    }
}

//子类
class Zi extends Fu{
    //子类的成员变量
    int num=100;
    //子类重写父类的成员方法

    @Override
    public void show() {
        System.out.println("子类的成员方法");
    }
}

在这里插入图片描述

2.类和接口之间的关系:

类与接口之间的关系:类与接口之间的关系是实现的关系,并且可以多实现(也就是说一个类可以实现多个接口)
代码演示:

//接口,接口中的方法都是抽象方法,
//方法前有public abstract的默认修饰符
interface A{
 public abstract void a();
 public abstract void aa();
}

interface B{
    public abstract void b();
}
//类与接口之间的关系:类与接口的关系是实现关系
//也就是说一个类可以实现多个接口
class C implements  A,B
{
    @Override
    public void aa() {

    }
    @Override
    public void a() {

    }
    @Override
    public void b() {

    }
}
3.接口和接口之间的关系:

接口与接口之间的关系:接口与接口关系是继承关系,并且可以多继承
代码演示:

interface A{
    public abstract void a();
}

interface B{
    public abstract void b();
}

//接口与接口之间的关系:是继承的关系,并且可以多继承
interface C  extends A,B{
    public abstract void c();
}
4.接口的注意事项:
  • JDK1.8前,接口中全是抽象方法;JDK1.8后,对接口进行一些改变,接口中的方法可以给出具体的实现(这个方法可以是非抽象方法),要在方法前有default修饰符
  • JDK1.8后,接口中可以定义静态方法

对于注意事项中的代码演示:

public class MyTest {
    public static void main(String[] args) {
        //JDK1.8之后,对接口有所改变
        //JDK1.8之后,可以定义默认方法,给出方法的具体实现,个人认为他是为了弥补类的单继承的不足。
        //JDK1.8之后,可以定义静态方法。

        Y y = new Y();
        y.hh();
        y.gg();
        GG.myGG();
    }
}

class AA {
    public void aa() {
    }
}

class BB {
    public void bb() {
    }
}

interface GG {
    default void gg() {
        System.out.println("gg");
    }
    public static void myGG() {
        System.out.println("ggg");
    }
}

interface HH {
    default void hh() {
        System.out.println("hh");
    }
}

class F extends AA {
}

class Y implements GG, HH {
}

interface A {
    void aa();
    void bb();
    public default void cc() {
        System.out.println("ccc");
    }
}

在这里插入图片描述

五.抽象类与接口之间的区别:

抽象类和接口之间的区别在于以下三个方面:

  • 成员区别:
类别成员变量的区别构造方法成员方法
抽象类可以是变量,也可以是常量有构造方法可以有抽象方法,也可以有非抽象方法
接口全部都是公共的静态常量无构造方法成员方法只有抽象方法(JDK1.8之后可以定义default修饰的方法,可以给出功能的具体实现,子类可以继承使用; JDK1.8之后在接口中也可以定义静态方法
  • 关系区别:
类、接口的关系
类与类之间的关系:继承关系,继承关系是单继承,不能多继承,可以多层继承
类与接口之间的关系:实现关系,可以单实现,可以多实现(一个类可以实现多个接口)
接口与接口之间的关系:继承关系,可以单继承,可以多继承
  • 设计理念区别:
设计理念区别
抽象类:抽象类中定义了该继承体系中的共性功能
接口:接口中定义的是该继承体系中的扩展功能

六.关于接口的练习:

练习内容:
猫狗测试之多态+接口版
源代码:

package JiekouChouxiangDemo;

public class DogAndCatInDuoTai {
    public static void main(String[] args) {
        Cat lhm = new LiHuaCat();
        lhm.age=2;
        lhm.name="狸花猫";
        System.out.println(lhm.name+"."+lhm.age);
        lhm.eat();
        lhm.sleep();
        LiHuaCat lihuamao = (LiHuaCat) lhm;
        lihuamao.cathMouse();
        System.out.println("----------------------------------");
        JiaFeiCat jfm = new JiaFeiCat();
        lhm = jfm;
        lhm.name = "加菲猫";
        lhm.age = 3;
        System.out.println(lhm.name+"."+lhm.age);
        lhm.eat();
        lhm.sleep();
        Jumpinterface jumpinterface = jfm;
        jumpinterface.jump();
        System.out.println("----------------------------------");
        Dog dog = new ErHa();
        dog.name="二哈";
        dog.age=4;
        System.out.println(dog.name+"."+dog.age);
        dog.eat();
        dog.sleep();
        ErHa erha = (ErHa) dog;
        erha.lookDoor();
        System.out.println("---------------------------------");
        JiWaWa jww = new JiWaWa();
        dog=jww;
        dog.name="吉娃娃";
        dog.age=5;
        dog.eat();
        dog.sleep();
        Jumpinterface jumpinterface1 = jww;
        jumpinterface.jump();
    }
}

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

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

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

    @Override
    public void sleep(){

    }
}

class JiaFeiCat extends Cat implements Jumpinterface{
    @Override
    public void eat() {
        System.out.println("加菲猫爱吃鱼罐头");
    }

    @Override
    public void sleep() {
        System.out.println("加菲猫睡席梦思");
    }

    @Override
    public void jump() {
        System.out.println("加菲猫学会了跳高");
    }
}

class LiHuaCat extends Cat {
    @Override
    public void eat() {
        System.out.println("狸花猫吃老鼠");
    }

    @Override
    public void sleep() {
        System.out.println("狸花猫睡蒲团");
    }

    public void cathMouse(){
        System.out.println("狸花猫会抓老鼠");
    }
}

class ErHa extends Dog{
    @Override
    public void eat() {
        System.out.println("二哈爱吃排骨");
    }

    @Override
    public void sleep() {
        System.out.println("二哈睁眼睡觉");
    }

    public void lookDoor(){
        System.out.println("二哈看门");
    }
}

class JiWaWa extends Dog implements Jumpinterface{
    @Override
    public void eat() {
        System.out.println("吉娃娃爱吃高级狗粮");
    }

    @Override
    public void sleep() {
        System.out.println("吉娃娃爱睡在狗窝");
    }


    @Override
    public void jump() {
        System.out.println("吉娃娃学会了跳高");
    }
}

运行截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值