JAVASE 包+面向对象

 

包 (package) 是 组织类的一种方式.
使用包的主要 目的是保证类的唯一性.

导入包中的类

可以使用 import 语句导入包,import 只能导入一个具体的类,而不能导入一个具体的包
比如:import java.util.Date;

将类放到包中

包名需要 尽量指定成唯一的名字, 通常会用 公司的域名的颠倒形式(例如 com.bit.demo1 ).
包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
如果一个 类没有 package 语句, 则该类被 放到一个默认包中

包的访问权限控制

如果 某个成员不包含 public 和 private 关键字, 此时这个成员可以在 包内部的其他类使用, 但是 不能在包外部的类使 .

常见的系统包


继承

对共性的抽取
使用 extends关键字进行处理的
意义:可以 对代码进行重复使用
继承是 is a("是") 的关系:比如Dog is a Animal

举一个继承的例子:

时刻牢记, 我们写的类是现实事物的抽象. 而我们真正在公司中所遇到的项目往往业务比较复杂, 可能会涉及到一系列复杂的概念, 都需要我们使用代码来表示, 所以我们真实项目中所写的类也会有很多. 类之间的关系也会更加复杂.
但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了.如果想从语法上进行限制继承, 就可以使用 final 关键字

final关键字

曾经我们学习过 final 关键字, 修饰一个变量或者字段的时候, 表示 常量 (不能修改).
f inal 关键字也能修饰类, 此时表示被修饰的类就不能被继承.(限制类被继承)

简单总结:


组合

和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果.
组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段
组合表示 has - a ("包含")语义(比如下面这个例子,学校有若干老师和学生)

多态

多态的前提:

1.向上转型:父类的引用指向子类引用的实例

向上转型发生的三种时机:直接赋值,方法传参,方法返回

直接赋值:

 方法传参:

方法返回: 

2.动态绑定(运行时绑定):

什么叫动态绑定:

在 Java 中, 调用某个类的方法, 如果父类和子类中有同名方法,究竟执行哪个类中的代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定.

举一个动态绑定的例子:

所谓"动态":

动态绑定的前提:

3.方法重写:

针对上面举的动态绑定的例子中的 eat 方法来说:子类实现父类的同名方法, 并且参数的类型和个数完全相同, 这种情况称为 覆写/重写/覆盖(Override)

 

重写的注意事项:

重写方法时显式加上 @Override 注解
 重写和重载的区别

理解多态

有了向上转型,动态绑定,方法重写的前提,就可以使用多态了!!
让我们来理解一下多态:(举一个打印多种形状的例子)
分割线上方是类的实现者
                                                                              分割线下方是类的调用者
通过这个例子发现:当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当前的 shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现 (和 shape 对应的实例相关), 这种行为就称为 多态.
多态顾名思义, 就是 "一个引用, 能表现出多种不同形态"
使用多态的好处:
1) 类调用者对类的使用成本进一步降低.
封装是让类的调用者不需要知道类的实现细节.而多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可.
因此, 多态可以理解成是封装的更进一步, 让类调用者对类的使用成本进一步降低.
2) 能够降低代码的 "圈复杂度", 避免使用大量的 if - else
3) 可扩展能力更强.
如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.
静态绑定:(编译时绑定)
利用重载来实现多态
向下转型:(没有向上转型用的多,并且是不安全的)
父类对象转化为子类对象
我们来看下面这个例子:

为什么会出现编译出错呢?

那么想要实现想要实现上面fly的效果,就需要向下转型:

super关键字

前面的代码中由于使用了重写机制, 调用到的是子类的方法. 如果需要在子类内部调用父类方法可以使用super 关键字

super 表示获取到父类实例的引用

super涉及两种常见用法:

1) 使用了 super 来调用父类的构造器

举例:

2) 使用 super 来调用父类的普通方法

在这个代码中, 如果在子类的 eat 方法中直接调用 eat (不加super), 那么此时就认为是调用子类自己的 eat (也就是递归了). 而加上 super 关键字, 才是调用父类的方法.

注意:super不能出现在静态方法中,并且super必须在方法中的第一行

 这里注意需要区分:
this和super的区别

在构造方法中调用重写的方法(一个坑)

简单总结:


抽象类

下面这个代码是我们上面在理解多态处举得例子中的代码,我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法(abstract method), 包含抽象方法的类我们称为 抽象类(abstract class).

在 draw 方法前加上 abstract 关键字, 表示这是一个抽象方法. 同时抽象方法没有方法体(没有 { }, 不能执行具体代码).
对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.

抽象类的作用:

抽象类存在的最大意义就是为了被继承.
抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.

 接口

接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量.

接口用在什么地方:
有的时候我们需要让一个类同时继承自多个父类,但一个类只能 extends 一个父类. 但一个类可以同时 实现多个接口, 也能达到多继承类似的效果.
举一个例子:

三个常用接口:

注意:如果自定义的数据类型进行大小的比较,一定要实现可以比较的接口!!!!

1.Comparable

Comparable和compare to是配套使用的
缺点:对类的侵入性太强了,一旦写好了就不能动了,比如原来是通过年龄比较大小,现在想改成通过分数比较大小就不行.
比如下面的例子

2.Comparator(推荐)

Comparator和compare配套使用

一般选择用Comparator而不用上面的Comparable,因为Comparator的优点是:灵活,对类的侵入性弱,想换比较就可以换.

例子如下面的代码所示
3.Cloneable
需要三步:
创建对象的方式:
之前我们学了new对象的方法创建对象,这里又学了一个通过clone()创建对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值