java面向对象编程的特征(查漏补缺)

Author Avatar
Sarience 4月 25, 2017
  • 在其它设备中阅读本文章

封装

  1. 信息的隐藏以及行为实现细节的隐藏。
  2. 维护数据的一致性和安全性
  3. 缩小访问权限(private),将信息私有化话之后,如果需要和其他对象之间进行交流,可以通过提供统一访问入口的方法提供给所有人统一访问方式。

继承

目的:父类代码的复用。简化子类构建过程。
Note:
1.满足is a或者is kind of语义关系
2.子类可以继承父类所具有的属性和行为。
3.子类还可以具有比父类更多的特征。
4.子类可以具有和父类完全同名的方法,子类可以覆盖父类本身所具有的行为。
5.子类可以 具有和父类完全一致的属性。
6.可以使用父类类型的变量接收子类类型的对象实例

引用类型数据类型转换:

1.隐式:
    父类类型的引用指向子类对象
    ShoutAnimal an = new Dog();
2.显示:
    Dog d = (Dog)an;
    Cat c = (Cat)an;
只要满足继承关系的子父类在进行强制(显示)类型转换时,编译期语法都可以通过,但是运行时有可能出现跨种族转换(虚拟机抛出ClassCastException),为了在运行时减少类型转换异常,推荐,在使用引用类型的强制类型转换之前先使用instanceof判断是否能够进行转换。
an instanceof ShoutAnimal :  true
an instanceof Dog:             true
an instanceof Cat:             false

Tips:若子类强转为父类,则父类的引用指向子类的对象,这话没错,但是,也只能说半对,为啥,来看看这段代码和运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.douya.Test;
/**
* Created by douya on 17-4-25.
*/
public class Test {
public static void main(String[] args) {
A b2a = new B("I'm B");
System.out.println(b2a.name);
b2a.pr();
}
public static class A {
String name;
public A() {
}
public A(String name) {
this.name = name;
}
public void pr() {
System.out.println(name);
}
}
public static class B extends A {
String name;
public B() {
}
public B(String name) {
this.name = name;
}
public void pr() {
System.out.println(name);
}
}
}

运行结果:

null
I’m B

代码很简单,就是子类与父类具有共同的方法和属性,在main中,创建了一个子类对象B,隐式转换成父类A,并使用该引用b2a访问属性name,访问方法pr()。调用方法不难理解,但是调用属性肯定很多人会理解错,认为结果应该是传入的值I'm B,但是运行结果摆在这里了,我们就好好来理解一下吧。(关于默认修饰符protect修饰的属性能不能继承请看:传送门,这里就不再展开讲了)

  1. 在执行new B("I'm B");的时候发生了什么呢,当然是先创建了父类A,后创建了子类B(若子类中有静态方法,则先执行父类的静态方法,后执行子类静态方法,然后依次执行父类代码块和构造方法,再依次执行子类代码块和构造方法:详情参考)。

  2. 那么A b2a中的b2a指向的是父类还是子类B呢,一般书上都会讲是指向子类B,这样说没错,但严格意义上是指向父类的,指向子类还是父类是由类型修饰符来决定的,这里是A,所以,b2aname属性取用的是父类的name,而父类的name没有赋值,即为空值null,如下图:

多态

1. 运行时多态
 相同类域的不同对象在调用相同方法时的表现不同
方法的重写
    1. 有子父类继承关系存在/接口和实现类关系
    2. 子类覆盖父类的行为/实现类实现接口中的方法
    3. 父类类型的引用指向子类对象/接口类类型的引用指向实现类的对象
    4. 调用被 重写了的方法/调用被实现了的方法
2. 编译时多态
    方法的重载
    
1
2
3
4
5
6
7
8
class Shape{
getArea(int r){
System.out.println("圆形");
}
getArea(int a,int b){
System.out.println("三角形");
}
}