封装、多态和继承是面向对象编程的三大特性
除了以上三大特征,我们也要熟悉其他概念,例如包,组合,抽象类,接口等。
封装
<<
代码大全
>>
开篇就在讨论一个问题
:
软件开发的本质就是对程序复杂程度的管理
.
如果一个软件代码复杂程
度太高
,
那么就无法继续维护
.
如何管理复杂程度
?
封装就是最基本的方法
.
在我们写代码的时候经常会涉及两种角色
:
类的实现者
和
类的调用者
.
封装的本质就是让类的调
用者不必太多的了解类的实现者是如何实现类的, 只要知道如何使用类就行了.这样就降低了类使用者的学习和使用成本
,
从而降低了复杂程度。
private实现封装
private/ public 这两个关键字表示 "访问权限控制"
被
public
修饰的成员变量或者成员方法
,
可以直接被类的调用者使用
.
被
private
修饰的成员变量或者成员方法
,
不能被类的调用者使用.
包
private/ public 这两个关键字表示 "访问权限控制"
被
public
修饰的成员变量或者成员方法
,
可以直接被类的调用者使用
.
被
private
修饰的成员变量或者成员方法
,
不能被类的调用者使用.
包
包(package)是组织类的一种方式
使用包主要目的是保证类的唯一性
可以使用import语句导入包,如果需要java.util中的其他类,可以使用ipmore java.util.*(但是是我们更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.)
包的访问权限控制
我们已经了解了类中的
public
和
private. private
中的成员只能被类的内部使用
.
如果某个成员不包含
public
和
private
关键字
,
此时这个成员可以在包内部的其他类使用
,
但是不能在包外部的类使用
.
常见的系统包
1. java.lang:
系统常用基础类
(String
、
Object),
此包从
JDK1.1
后自动导入。
2. java.lang.reflflect:java
反射编程包
;
3. java.net:
进行网络编程开发包。
4. java.sql:
进行数据库开发的支持包。
5. java.util:
是
java
提供的工具程序包。
(
集合类等
)
非常重要
6. java.io:I/O
编程开发包。
继承
背景
代码中创建的类
,
主要是为了抽象现实中的一些事物
(
包含属性和方法
).
有的时候客观事物之间就存在一些关联关系
,
那么在表示成类和对象的时候也会存在一定的关联
.
例如
,
设计一个类表示动物
// Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Cat.java
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
// Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Cat.java
class Cat {
public String name;
public Cat(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
// Bird.java
class Bird {
public String name;
public Bird(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
这个代码我们发现其中存在了大量的冗余代码。 此时我们就可以让 Cat 和 Bird 分别继承 Animal 类, 来达到代码重用的效果。
此时 , Animal 这样被继承的类 , 我们称为 父类 , 基类 或 超类 , 对于像 Cat 和 Bird 这样的类 , 我们称为 子类 , 派生类和现实中的儿子继承父亲的财产类似 , 子类也会继承父类的字段和方法 , 以达到代码重用的效果。 语法规则 使用 extends 指定父类 . Java 中一个子类只能继承一个父类.(单继承语言) 子类会继承父类的所有 public 的字段和方法. 对于父类的 private 的字段和方法 , 子类中是无法访问的 . 子类的实例中 , 也包含着父类的实例 . 可以使用 super 关键字得到父类实例的引用.此时对于上面的代码我们就可以使用继承改进
class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.name + "正在吃" + food);
}
}
class Cat extends Animal {
public Cat(String name) {
// 使用 super 调用父类的构造方法.
super(name);
}
}
class Bird extends Animal {
public Bird(String name) {
比特科技
super(name);
}
public void fly() {
System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
}
}
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("小黑");
cat.eat("猫粮");
Bird bird = new Bird("圆圆");
bird.fly();
}
}
如果我们把
name
改成
private,
那么此时子类就不能访问了,此时我们就可以使用protected关键字.
protected关键字
刚才我们发现
,
如果把字段设为
private,
子类不能访问
.
但是设成
public,
又违背了我们
"
封装
"
的初衷
.两全其美的办法就是
protected
关键字。
对于类的调用者来说
, protected
修饰的字段和方法是不能访问的
对于类的
子类
和
同一个包的其他类
来说
, protected
修饰的字段和方法是可以访问的
小结
: Java
中对于字段和方法共有四种访问权限
private:
类内部能访问
,
类外部不能访问
默认
(
也叫包访问权限
):
类内部能访问
,
同一个包中的类可以访问
,
其他类不能访问
.
protected:
类内部能访问
,
子类和同一个包中的类可以访问
,
其他类不能访问
.
public :
类内部和类的调用者都能访问
访问权限:public>protected>default>private
final
关键字
final 关键字的功能是 限制 类被继承
组合
和继承类似
,
组合也是一种表达类之间关系的方式
,
也是能够达到代码重用的效果。
组合表示
has
-
a
语义
继承表示
is
-
a
语义
多态(难点)
向上转型
子类对象/引用 给父类就称为向上转型。
注:向上转型之后 只能通过父类的引用访问父类自己特有的方法和属性,不能访问子类特有的属性和方法
向下转型(不推荐) 向上转型是子类对象转成父类对象 , 向下转型就是父类对象转成子类对象 . 相比于向上转型来说 , 向下转型没那么常见 ,但是也有一定的用途 动态绑定(运行时绑定)满足条件:1.向上转型 2.通过父类引用调用父类和子类的同名覆盖方法,此时就会发生运行时绑定。那么覆盖又是什么意思呢?
方法重写 子类实现父类的同名方法 , 并且参数的类型和个数完全相同 , 这种情况称为 覆写 / 重写 / 覆盖 (Override) 注意事项: 1.重写中子类的方法的访问权限不能低于父类的方法访问权限 . 2.重写的方法返回值类型不一定和父类的方法相同 ( 但是建议最好写成相同 , 特殊情况除外 ) 3.普通方法可以重写 , static 修饰的静态方法不能重写 . 4.private方法也不可以重写 5.如果一个方法被final修饰,也不可以被重写 理解多态 多态顾名思义, 就是 "一个引用, 能表现出多种不同形态" 无论是哪种编程语言 , 多态的核心都是让调用者 不必关注对象的具体类型 . 这是降低用户使用成本的一种重要方式 。


