一、封装(Encapsulation)
-
private public protected提供了访问权限控制,这三个关键字还有一个默认包为封装提供了前提,可以通过这几个实现是否对外界信息隐藏,以及隐藏的程度。
-
访问权限控制控制常被称为是具体实现的隐藏。把数据和方法包装进类里,以及具体实现的隐藏,常共同被称作封装。
-
import,package这两个关键字能够避免命名冲突和类的访问问题。这样封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。如果不知道类的全路径,不用import导入,永远无法访问到那个类(java所有类都默认导入java.lang.*,还有如果是一个包下面的,可以不用import)。
二、继承(Inheritance)
-
当创建一个类时,总是在继承,如果没有指定特定的类继承,那么默认继承根类java.lang.Object. 不用导包,因为是java.lang下的。
-
使用extends实现继承,java只支持单继承,一个类的父类只有一个。
-
子类继承父类的非私有属性和方法
-
继承可以传递,可以使用父类的父类的非private方法和属性。
-
继承降低了代码的冗余,更利于维护与阅读。
三、多态(Polymorphism)
1. 向上转型
-
子类的对象可以指向父类的引用。
-
子类的引用可以替代父类的引用。
-
把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
package com.thinkInJava; public class Test { public static void main(String[] args) { A a = new A(); B b1 = new B("b1"); A b2 = new B("b2");//子类的对象可以指向父类的引用 Test test = new Test(); test.show(a); test.show(b1);//子类的引用可以替代父类的引用 test.show(b2); } void show(A a){ System.out.println(a.toString()); } } class A{ public String toString() { return super.toString(); } } class B extends A{ String name; public B(String name){ this.name=name; } public String toString() { return name; } } //输出 //com.thinkInJava.A@15db9742 //b1 //b2
2. 方法绑定:前期绑定与后期绑定
-
将一个方法调用同一个方法主体关联起来被称为绑定。
-
在程序执行器前绑定成为前期绑定(前期绑定),在程序执行时绑定为后期绑定(动态绑定)
-
c语言中只有前期绑定,在编译过程中,就知道调用哪个方法。
-
java中除了static,final(private包括其中)之外都是动态绑定,在运行时,根据引用指向的对象的具体类型,调用它的方法。
-
以上面的程序为例子
void show(A a){ System.out.println(a.toString()); }//光看这段代码,会执行a的toString方法,在编译期间,编译器一直不知道对象的类型, // 只知道这是A的引用,如果传一个类C的引用(C不指向A或A的子类对象),编译器会报错, // 这会在编译器执行。但实际上如果用A的子类对象的引用传进来,编译通过,但在运行时, // 会判断这个引用究竟指向哪个对象,执行这个对象所指向类的方法。
java通过动态绑定实现多态
3. 重写(Override)与重载(Overload)
- 重写是多态 重写在编译期无法确定,要到运行时才能判断是否重写,执行哪个方法,在上面程序中,子类重写了父类的toString方法。
- 重载不是多态 在编译期间,就已经找到要执行那个方法,你写两个相同方法,会报错,因为编译器已经检查到了两个相同方法,重载方法编译器也能检测到,知道具体执行哪个方法。
4. java中多态
-
java中多态动态绑定也只是绑定方法,不能是属性。当调用父类引用的属性时,即使引用指向子类对象,这个属性是父类的属性,而不是子类的。
package com.thinkInJava; public class Test { public static void main(String[] args) { A a = new A(); B b1 = new B("b1"); A a1 = new B("b2"); Test test = new Test(); test.show(a); test.show(b1); test.show(a1); } void show(A a){ System.out.println(a.name); } } class A{ String name = "A"; public String toString() { return super.toString(); } } class B extends A{ String name = "B"; public B(String name){ this.name=name; } public String toString() { return name; } } //输出 //A //A //A