面向对象编程
- 包
- 继承
包
包(package)是组织类的一种方式
使用包的主要目的是保证类的唯一性
列如你的代码写了一个Test类,你同事可能也写了一个Test类,如果出现同名的类就会冲突,导致代码编译不过。
导入包中的类
java中已经提供了很多现成的类供我们使用。
例如:得到一个毫秒级别的时间戳可以使用java.util.Data
这种方式引入了java.util
这个包中的Data
类
但是这种写法比较麻烦一些,可以使用import
语句导入包
注意事项import
和C++的#include
差别很大。C++必须#include
来引入其他文件内容,但是java不需要,import
只是为了写代码的时候更方便。import
更类似与C++中的namespace
和using
。
静态导入
使用import static
可以导入包中的静态的字段和方法
使用这种方法可以更方便的写一些代码
但是我不建议这种写法,多写一点没什么不好的
将类放到包中
基本规则
- 在文件的最上方加一个paceage语句指定该代码在那个包中
- 包名需要尽量指定成一个唯一的名字,通常会用公司域名的颠倒形式(例如
com.bit.demo1
) - 包名要和代码路径相匹配。
- 如果一个类没有package包,则该类被放到一个默认包中
操作步骤
1.在IDEA中先新建一个包
2.在弹出的框中输入包名
3.在包中创建类。
4.此时我们可以看到磁盘上得目录结构已经被IDEA自动创建出来了
5.同时我们也可以看到在创建的Test.java
文件的最上方,就出现了一个package语句
包的访问权限控制
我们已经了解到类中的public
private
private
中的成员只能被类的内部使用
如果某个成员不包含public
private
关键字,此时这个成员可以在包内部的其他类使用,但是不能在包外部的类实用
下面的代码给了一个示例。Demo1和Demo2是同一个包中,Test是其他包中
如果在同一个包中可以访问。但是如果在不同包中就会报错
常见的系统包
1.java.lang:系统常用基础类(String、Object)此包从JDK1.1之后自动导入
2.java.lang.reflect:java反射编程包
3.java.next:进行网络编程开发包
4.java.spl:进行数据库开发的支持包
5.java.util:是java提供的工具程序包(集合类等)非常重要
6.java.io: I/O编程开发包
继承
背景
代码中创建的类,主要是为了抽象现实中的一些事物(包含属性和方法),有的时候客观事物之间存在一些关联联系,那么在表示成类和对象的时候也会存在一定的联系
例如:设计一个类表示动物
在这个代码中我们发现了大量的冗余代码我们发现
Animal
和Cat
Bird
这几个类中存在一定的关联和联系、
- 这三个类都有一个eat方法,而且行为是完全一样的
- 这三个类都有一个name属性,而且意义是完全一样的
- 从逻辑上讲Cat和Bird是一种Animal(is - a 语义)
此时我们就可以让Cat 和Bird分别继承Animal类来达到代码重用的效果
Animal这样被继承的类我们称之为父类 、基类、超类 ,对于Cat和Bird这样的类,我们称之为子类,派生类,和现实中儿子继承父亲的财产类似,子类也会继承父类的字段和方法,一达到代码重用的效果
语法规则
- 使用extends指定父类
- java中一个子类只能继承一个父类(而C++/Python等语言支持多继承)
- 子类会继承父类所有的
public
字段和方法 - 对于父类中的
private
的字段和方法,子类是无法访问的 - 子类的实例中,包含着父类的实例,可以使用
super
关键字得到父类实例的引用
protected关键字
刚才我们发现,如果把字段设为private
,子类不能访问,但是设为public
,又违背了我们“封装”的初衷。两全其美的办法就是protected
关键字
- 对于类的调用者来说,
protected
修饰的字段和方法是不能访问的 - 对于类的子类和同一个包的其他类来说,
protected
修饰的字段和方法是可以访问的
小结:java中对于字段和方法共有四种访问权限
private
类内部能访问,类外部不能访问- 默认(也叫包访问权限):类内部能访问,同一个包中的类可以访问,其他类不能访问
protected
:类内部能访问,子类和同一个包中的类能访问,其他类不能访问public
:类内部和类的调用者都能访问
什么时候下用哪一种那?
我们希望类要尽量做到“封装”,即隐藏内部实现细节,只暴露出必要的信息给使用者
因此在使用的时候应该尽可能的使用比较严格的访问权限。例如一个方法能用
private
就尽量不用public
另外,还有一种简单粗暴的方法:将所有的字段设为
private
,将所有的方法设为public
,不过这种方式属于是对访问权限的滥用,还是在写代码的时候要认真思考,该类提供的方法到底给‘谁’使用(是类内部自己用,还是类的调用者使用,还是子类使用)
更复杂的继承关系
例如
如果像上图这样继承方式为多层继承,即子类还可以在进一步的派生出新的子类
时刻牢记我们写的类是现实事物的抽象,而我们真正在公司中所遇到的项目往往业务比较复杂,可能涉及到一系列复杂的概念,都需要我们使用代码来表示,所以真实的项目中所写的类也会有很多,类之间的关系也会更加的复杂
但是即使如此,我们并不希望类之间的继承层次太复杂,一般我们不希望出现超过三层的继承关系,如果继承层次太多,就需要考虑对代码进行重构了
如果想从语法上限制继承,可以使用
final
关键字
final关键字
曾经我们学习过final
关键字,修饰一个变量或者字段的时候,表示常量(不能修改)
final
关键字也能修饰类,此时表示被修饰的类不能被继承
final
关键字的功能是限制类被继承“限制”这件事意味着“不灵活”,在编程中灵活不见得是一件好事,灵活可能意味着更容易出错
是用
final
修饰的类被继承的时候,就会编译报错,此时就可以提示我们这样的继承是有悖这个类设计的初衷