抽象类 接口 包

回忆

  • 方法重写
    • 指的是 子类中定义 了跟父类(父代)方法签名一致
      • 返回值类型 方法名 参数列表 必须一致
      • 修饰符 不能比父类的 权限低
    • 用途:
      • 子类要完全修改父类的行为
      • 子类要扩展父类的行为
  • final
    • 修饰的内容不同意义不同
    • 修饰类:表示类不能被继承
    • 修饰成员方法: 表示方法不能被重写
    • 修饰局部变量: 是一个常量
    • 修饰成员变量:是一个常量,且不能使用默认值,必须显式赋一次值。
  • 多态
    • 同一个事物在不同时刻的不同体现
    • 父类型 变量名 = 子类型变量;
      • 要继承(建立父类和子类的关系)
      • 重写
    • 成员变量
      • 编译看左边,运行看左边
    • 成员方法
      • 编译看左边,运行看右边
    • 静态变量
      • 编译看左边,运行看左边
    • 静态方法
      • 编译看左边,运行看左边
    • 所谓的弊端:当我需要访问子类特有的行为时,必须向下转型
      • 强转: 子类类型 变量名 =(子类类型)父类变量;
        • 当两个类型不具备继承关系时,不能使用强转,就发生编译错误。
        • 即使两个类有继承关系,如果它引用的对象不是某个子类,运行时也会发生异常:
        • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eSAovdN3-1593181447753)(imges/image-20200622093319513.png)]
        • 如何确保这个转换可以安全的进行呢?
          • instanceof 关键字配合if来使用。
          • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjXCywR0-1593181447755)(imges/image-20200622093704527.png)]
    • 方法相关特点:
      • 当父类型作为方法参数时,调用时可以传递 父类类型的对象或子类类型的对象(多态)。
      • 当父类型作为方法返回值时,也可以返回 父类类型的对象或子类类型的对象(多态)。

抽象类

当某个类表示一种抽象的概念的时候,new它没有实际意义。所以会考虑将它设置为抽象类。

标识抽象类的方式也很简单,只需要在 class 关键字前面添加 abstract 修饰符即可。

abstract class ClassA{
    //定义了一个抽象类 ClassA
}

其实,Java中还存在一种更细粒度的抽象,称为:抽象方法
当父类中的某个方法总是会被子类所重写,那么在父类中实现该方法也是没有实际意义的。此时,应该将该方法声明为抽象方法。

将一个方法声明为抽象方法:

  • 在返回值类型前面添加关键字 abstarct
  • 去掉大括号(意味着抽象方法没有方法体),注意分号不能丢
其它修饰符 abstract 返回值类型 方法名(参数类型 参数名,....);

注意事项

  • 一个抽象类中可以包含所有非抽象的内容
  • 一旦一个类中包含了抽象的方法,这个类必须声明为抽象类。
  • 如果一个抽象类中包含了抽象方法,其子类的选择
    • 子类也可以是抽象类
    • 子类可以是具体类,必须实现(重写)父类的抽象方法 ,可以选择性的重写父类的其它成员方法。
  • 抽象类照样可以包含构造方法
    • 抽象类中的构造方法往往用于数据的存储。

练习:

老师、学生

都是人。都具备姓名、年龄。有差异。

​ 都能吃饭、睡觉。一个学习,一个授课。

你来完善它们的完整的OOP的内容。

思考

  1. 抽象类一定是父类 ? 是
  2. 如果一个类没有抽象方法,能否定义成抽象类?可以。
    1. 又有什么意义呢?不想直接让用户实例化它。
  3. 你觉得abstract关键字跟哪些你学过的关键字冲突呢?
    1. private
    2. final
    3. static

接口

假设 狗能看门(有陌生人进来,就会叫唤-报警机制)。 现在,出现了智能摄像头(有陌生人进来,就会报警)… 分析,它们具备共同的行为,如何抽象呢?

首先考虑,继承可以吗?

  • 技术上可以。
  • 道理上说不通。那个父类是个什么玩意?因为继承往往体现的是 is a 的关系。所以,这种情况下,无法生搬硬套将它们归为一类。

此时,接口技术就可以来满足我们的需求。

接口更多的侧重点在于行为的抽象。

万事万物都有行为,都可以用接口来描述。

java语言对接口的支持需要配合关键字 interface ,仍然定义在 .java 文件中。且编译完之后仍会产生.class文件。所以,本质上 接口也是一种特殊类型的 类。

//定义格式
interface 接口名{ //将class关键字替换为 interface 关键字。
}

接口的组成

反编译工具:

  • 编译 .java -> .class
    • 可以引入一些代码混淆工具
    • 反编译 .class -> .java
  • 可以包含成员变量,且只能是常量,必须赋值且赋值一次。这些常量都是静态的
    • int a = 10
    • public int a = 10
    • public static int a =10
    • public static final int a =10
  • 不可以包含任何构造方法
  • 成员方法: 必须都是抽象方法
    • 非静态的方法必须去掉方法体,用分号结束。
    • 修饰符的部分:
    • void m1()
    • public void m1();
    • public abstract void m1();
  • 静态方法:正常写就ok。

接口的使用

  • 接口可以被其他接口继承

    • interface 接口1{
          
      }
      
      interface 接口2 extends 接口1{
          
      }
      
  • 接口可以被其他类实现 implements 关键字

    • interface 接口{
          
      }
      classimplements 接口{
          
      }
      

接口的特点

  • 类与类

    • 继承关系,只支持单继承,可以多层继承。
    • 通过final来阻断
  • 类与接口

    • 实现关系。既可以单实现,也可以多实现。最复杂的场景就是继承一个类的同时实现某些接口。
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EwXqCazG-1593181447757)(imges/image-20200622143951615.png)]
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZC7eQ1GF-1593181447759)(imges/image-20200622144049491.png)]
  • 接口与接口

    • 是继承关系。既可以单继承,也可以多继承。

接口和抽象类的区别

  • 成员上的区别
    • 接口 : 常量、抽象方法、静态方法。
    • 抽象类:变量、常量、成员方法、抽象成员方法、静态方法。
  • 关系上的区别
    • 类与类
    • 类与接口
    • 接口与接口
  • 设计理念上的差别
    • 抽象类是被继承的体现。 “is a”的关系,共性的功能
    • 接口被现实的体现。“like a”的关系,是一个扩展的功能。

练习体会。

老师、学生。抽象类的实现。

​ 老师中有一部分人要抽烟

​ Teacher implements XXX //意味着所有老师都要抽烟,不符合题干

​ XXXTeacher extends Teacher implements XXX //这里

​ 学生也有一部分人要抽烟。

如何来描述这种情况呢?试着改造一下原有的设计。

方法调用中参数和返回值的问题

  • 参数类型

    • 基本数据类型: 调用时要求什么类型就传递什么类型。或者能自动类型转换
    • 普通类:类的对象,或者子类对象。
    • 抽象类:一定是子类对象。
    • 接口:实现(可以是直接实现,也可以是间接实现)了该接口的对象。
  • 返回值类型

    • 基本数据类型: 要什么类型返回什么类型。或者能自动类型转换。

    • 普通类型: 类的对象,或者子类对象。

    • 抽象类:一定是子类对象。

    • 接口:实现(可以是直接实现,也可以是间接实现)了该接口的对象。

链式编程

比如说有一个对象,在正式使用之前需要设置大量的相关属性。

public class _10Chain {
    public static void main(String[] args) {
        Condition condition = new Condition();
        condition.setC1(1);
        condition.setC2(2);
        condition.setC3(3);
        condition.setC4(4);

        //进入下一步的逻辑.....
        //链式思想的 “类set方法” 都会原样返回对象本身
        Condition condition1 = new Condition()
                .C1(1)
                .C2(2)
                .C3(3)
                .C4(4);

    }
}

//表示飞行条件
class Condition{
    //风速
    private int c1;
    //湿度
    private int c2;
    //速度
    private  int c3;
    //能见度
    private int c4;

    public int getC1() {
        return c1;
    }

    public Condition C1(int c1){
        this.c1 = c1;
        return this;
    }
    public void setC1(int c1) {
        this.c1 = c1;
    }

    public int getC2() {
        return c2;
    }
    public Condition C2(int c2){
        this.c2 = c2;
        return this;
    }
    public void setC2(int c2) {
        this.c2 = c2;
    }

    public int getC3() {
        return c3;
    }
    public Condition C3(int c3){
        this.c3 = c3;
        return this;
    }
    public void setC3(int c3) {
        this.c3 = c3;
    }

    public int getC4() {
        return c4;
    }
    public Condition C4(int c4){
        this.c4 = c4;
        return this;
    }
    public void setC4(int c4) {
        this.c4 = c4;
    }
}

包其实就是文件夹。用来存放 .java 文件。目的是为了对Java类/接口…进行分类管理。之所以进行分类管理:

  • 相同方面的某些类放在一起,好找。
  • 解决类名冲突的问题。
    • java要求相同包下面只能包含唯一的类名。

声明语法:

package 包名;

//包名属于标识符。
//规范:
//1. 包名的所有字母全部小写
//2. 一般会采用以下模式来命名:
// 2.1 第一部分域名倒写。 比如百度公司的域名是 baidu.com, 所以,假设你是百度公司的程序员,那么我公司开发的Java程序的顶层包名:  com/baidu
// 2.2 第二部分是项目/软件/产品...其它代号。比如我的程序是百度公司的贴吧产品相关的源码。这层包就可以命名为: tieba
// 2.3 对于贴吧产品来说,也会进行进一步的分层,模块层面。比如回复模块,我的包名命名: reply
// 2.4 进一步回复模块内部,从技术上考虑也会分成不同的部分(技术层面,现在很可能无法深入的了解)。常见的内容如下:
entity/model/domain  .... 对应数据库的表
dao/impl  ..... 对应数据访问层的对象,就是如何操作数据库
service/impl ...... 对应业务逻辑
web/controller  ..... 对应界面逻辑
util .... 对应工具类
    
    
//总结,以XXX工具类来说,它应该放入包:
    com/baidu/tieba/reply/util/XXX.java
//对应的java语法的声明
   
    package com.baidu.tieba.reply.util;

如何被其他类所使用呢?在其它类的.java文件中,访问你的java类。

导入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cmpo4tAQ-1593181447761)(imges/image-20200622173437194.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2P98DDH-1593181447763)(imges/image-20200622173806561.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9TfNk1IQ-1593181447764)(imges/image-20200622174237055.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5pR7pyO-1593181447766)(imges/image-20200622174403734.png)]

静态导入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PeE9l95J-1593181447767)(imges/image-20200622175301667.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NC71oaFL-1593181447769)(imges/image-20200622175538565.png)]

注意事项

  • package 语句必须是程序中的第一条可执行语句(如果前面有注释是可以的)。
    • 可以省略。
    • 如果出现,只能出现一次。
  • import语句必须写在class的前面package的后面
    • 可以出现多次
  • 如果没有定义package,说明它是 “默认包” 下。
    • 非默认包下的类中无法导入 “默认包“ 下的类。反过来是成立的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值