day13_oop_抽象类_接口

本文详细介绍了Java中的抽象类、接口、成员内部类和匿名内部类的概念、语法特点、使用场景和目的。重点讲解了抽象方法的使用、接口的接口实现、以及内部类的不同类型及其在实际编程中的应用。
摘要由CSDN通过智能技术生成

今日内容

零、 复习昨日
一、作业
二、抽象
三、接口

零、 复习昨日

final的作用

  • 最终的,修饰的类,属性,方法不能改变
  • 类不能继承,属性不能改变(常量),方法不能重写

static修饰方法的特点

  • 修饰的属性方法在内存只有一份
  • 随着类加载而初始化
  • 不要new,可以通过类名直接调用
  • 被该类的所有对象共享(类属性,方法)
  • 静态不能调用非静态

多态效果形成的前提

  • 继承(子父类关系)
  • 重写
  • 向上转型(父类指向子类对象)

多态使用的场景

  • 方法的参数列表是父类,传入子类,方法执行时出现的各种子类效果
  • 数组是父类型数组,存储子类对象
  • ps: 多态是解决共性问题方便使用的

什么叫向下转型?如何才能转型成功?

  • 父对象变子对象(子类引用指向父类对象)
  • 先有向上,才能 向下
  • Animal a = new Dog();s
  • Dog dog = (Dog)a;
  • 什么时候需要? 当需要执行子类特有的方法时

一、作业

见代码

二、抽象

2.1 解释

生活抽象: 抽象画,抽象的故事 , 意思就是指看不明白,不懂…与具象化是反义词

代码的抽象: 主要是指抽象类和抽象方法

2.2 语法特点

类和方法如何变成抽象?有何特点?代码如何写?

  • 在class前面加abstract 修饰,类就变成抽象类
  • 抽象类中可以有正常属性,且不能抽象
  • 抽象类中可以有正常方法
  • 抽象类中可以有被abstract修饰的抽象方法,没有方法体!
  • 抽象方法必须 放在抽象类中
  • 抽象类中可以 有构造方法,且不抽象!但是不能直接new创建对象!

那么抽象类存在的目的意义是什么?

  • 抽象类是用来被继承的
  • 子类继承抽象类要求:
    • 要么子类定义成抽象类
    • 要么就必须重写(实现implement)全部抽象方法

// 抽象父类

package com.qf.abstract_;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @date 2024/1/31
 * @desc 演示抽象语法
 */
public abstract class Animal {
    // 属性没有抽象性
    int age;
    // 正常方法
    public void eat(){
        System.out.println("动物觅食" );
    }
	// 抽象方法
    public abstract void play();

    // 构造方法
    public Animal(){
        System.out.println("Animal()" );
    }
}

// 子类

public /*abstract*/ class Dog extends Animal{

    public Dog(){
        System.out.println("Dog()" );
    }

    @Override
    public void play() {
        System.out.println("小狗玩球" );
    }
}

// 测试

public class TestAbstract {
    public static void main(String[] args) {

        //  抽象类有构造方法,但是不能直接new创建对象!!
        // new Animal();

        // new Dog()还会调用Animal()构造方法
        Dog dog = new Dog( );
        System.out.println(dog.age );// 使用抽象父类的属性
        dog.eat();// 父抽象类方法

        // 抽象类可以当做父类引用指向子类对象
        Animal animal = new Dog();
        animal.eat();// animal自己的正常,执行
        animal.play();// 调用子类重写的执行,即多态效果
    }
}

2.3 什么用?

抽象类不能直接主动new创建对象,但是被继承后,创建子类对象时,还是会父类构造方法,因为子类还需要父类的非私有的属性和方法

image-20240131103530552

抽象类虽然不能直接new,但是可以当做父类引用,指向子类对象 —> 多态

image-20240131103749502

总结什么时候需要抽象类抽象方法?

  • 抽象差异化,具体共同点
    • 将很多类都有的共同方法抽取到父类中,大家共用
    • 很多类有共同的行为但是具体表现不一样,将这些方法定义成抽象,让子类自己实现

平时自己用,敲代码时,抽象有什么经验?

  • 1)用别人的抽象类时,一般要继承它,重写抽象方法即可
  • 2)做为设计者,设计抽象类,将共同能直接用的方法直接定义,子类都需要单独实现的定义成抽象
  • 现在抽象的用法与之前写代码几乎是一样用法,只不过多了一层限制,即必须重写抽象方法

2.4 练习

抽象类的使用,将之前做的所有练习将父类改成抽象类即可

  • 形状类变抽象
  • 员工类变抽象
  • 动物类变抽象

其他用法基本一样(继承,重写,向上转型)…

三、接口

java的引用数据类型: 数组,类,接口

接口是比抽象类还抽象的java文件

3.1 语法介绍

  • 接口不是类,需要使用interface修饰
  • 接口中没有属性变量,都是常量,默认都被public static final修饰
  • 接口中没有正常方法,全都是抽象方法,默认都被public abstract修饰
  • 接口中不能有构造方法,肯定不能创建对象

接口用来干什么呢? 用来被子类实现

  • 接口是用来被子类实现implements
  • 子类实现父接口,
    • 要么子类定义成抽象类
    • 要么子类重写(实现)全部抽象方法
  • 子类允许实现多个接口(多实现)
  • 子类还可以再继承的同时实现接口,注意先继承后实现

// 父接口

public interface USB {
    // 属性都是常量,默认被 public static final修饰
    public static final double length = 1;
    // 方法都是抽象,默认被public abstract修饰
    public abstract void send();

    // 没有构造
    // public USB(){}
}

// 子实现类

// 继承同时实现接口
// 且是多实现
public class UDisk extends Shape implements USB,Disk{

    @Override
    public void send() {
        System.out.println("U盘发送数据" );
    }

    @Override
    public void input() {
        System.out.println("U盘输入数据" );
    }

    @Override
    public void output() {
        System.out.println("U盘输出数据" );
    }
}

3.2 作用

接口虽然不创建创建对象,但是可以当做父引用去使用! 其实就是利用多态的特性,即

  • 提供扩展性
  • 减少耦合性

练习题:

今天以及以前那些多态题,抽象类的题其实都可以改造成接口去演示,基本上一致

3.3 和抽象的区别

代码语法上来说,区别

抽象接口
是类(class)不是类(interface)
属性有属性没有,全是常量
方法有正常方法,也有抽象全是抽象方法
构造方法构造方法没有
创建对象不能创建对象不能创建对象
应用当做父引用指向 子类当做父引用指向 子类

从应用角度来说,感觉用法很相似,都是当做父引用指向子类对象,即多态场景下使用!

既然差不多,为何需要接口?

  1. 如果只有抽象,一个类继承完抽象类还能再扩展吗? 不能!类是单继承
  2. 接口 是一种对接的思想,可以让类和类产生关系
  3. 抽象类至少还是类!类是描述一类物体! 接口是不是类,都是常量和抽象方法,所以接口是一种规范(约束,定义)
  4. 编程时,如何设计抽象还是接口呢?
    1. 能代表一类物体(物种),有共性可复用,又有特性的,那就设计成抽象类
    2. 能代表一类能力,行为,规范的这些定义成接口

编程经验

  • 后续写项目,会把接口的命名定义成IXxxx , IUsb
  • 实现类定义成 XxxImpl

3.4 练习

pdf8

五、内部类[了解]

内部类的概念:

在⼀个类中定义的类,称之为内部类(InnerClass),外⾯的类的称之为外部类(OutClass)

内部类的分类:

  • 1、成员内部类
  • 2、静态内部类
  • 3、局部内部类
  • 4、匿名内部类

内部类的特点:

  • 1、内部类可以访问到外部类的私有成员,且不破坏封装性
  • 2、内部类也会生成.class⽂件。名为:外部类名$内部类名.class

外部类的特点:

  • 一个java 文件中可以编写多个类,但是只能有一个类能使用public修饰,称之为主类。主类名必 须与文件名⼀致
  • 建议:以后开发中,一个java文件就编写⼀个类

5.1 成员内部类

成员内部类

  • 1、成员内部类中只能定义非静态属性和方法
  • 2、成员内部类中可以访问外部类的成员,私有的可以,静态的也可以
  • 3、成员内部类如何创建对象
    • 语法: 内部类 对象名 = new 外部类().new 内部类();
public class Outer {

    private int outer = 1;
    void testOuter(){
        // 外部不能用内部
       // System.out.println(inner );
    }
  // 成员内部类
    public class Inner {
        int inner = 2;
        void testInner(){
            // 内部可以用外部
            System.out.println(outer );
        }
    }
}

5.2 匿名内部类 [熟悉]

匿名内部类:本⾝就是⼀个对象

语法:

new ⽗类(){ 
    重写⽗类的⽅法 
}

特点:

  • 1、匿名内部类本⾝就是⼀个对象
  • 2、⼀般在匿名内部类中不会定义属性和⽅法,因为没有意义
  • 3、匿名内部类的⽗类⼀般都是抽象类或者是接口

匿名内部类的应用场景

  • 如果一个方法的参数是接口,且这个接口只需要实现一次,那么就可以使用匿名内部类

// 接口

public interface USB {
    void chuanshu();
}

// 测试

package com.qf.oop3;

/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc
 */
public class TestInnerClass {

    public static void main(String[] args) {

        /**
         * 按以前,需要新建一个类实现USB接口,创建子实现类对象
         * 但是如果该接口的方法只需要实现一次,那么这么做就浪费时间
         *
         * 可以使用匿名内部类来简写
         * 匿名内部类
         *  new 接口(){
         *      重写方法()
         *  }
         * 相对于是,实现了接口并重写了方法且创建了子类对象
         */
        new USB() {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        }.chuanshu();

        System.out.println("---------" );
        // 匿名内部类相当于创建了子类对象,所有也可以使用父类类型接收
        USB usb = new USB() {

            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        };
        usb.chuanshu();
        System.out.println("-----------" );
        // 当方法的参数列表是接口的时候,可以传入匿名内部类对象
        // 跟以前传入子实现类对象一个意思,只是简化了
        addUSB(new USB( ) {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        });

        addUSB(new USB( ) {
            @Override
            public void chuanshu() {
                System.out.println("U盘传输" );
            }
        });

    }

    public static void addUSB(USB usb) {
        usb.chuanshu();
    }

}

四、补充知识

成员内部类,静态 内部类,匿名内部类

构造代码块,局部代码块,静态代码块

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值