java的三大特征

java的三大特征

封装性,继承性和多态性

封装性

  • 我们程序设计追求“高内聚,低耦合”。
    • 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉
    • 低耦合 :仅对外暴露少量的方法用于使用
  • 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提 高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露 的暴露出来。这就是封装性的设计思想。
  • Java中通过将数据声明为私有的(private),再提供公共的(public) 方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:
  1. 隐藏一个类中不需要对外提供的实现细节;
  2. 使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑, 限制对属性的不合理操作;
  3. 便于修改,增强代码的可维护性;

继承性

  • 为什么要有继承?

    多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行为,只要继承那个类即可。

  • 此处的多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。

  • 类继承语法规则: class Subclass extends SuperClass{ }

  • 继承的作用:

    1. 继承的出现减少了代码冗余,提高了代码的复用性。
    2. 继承的出现,更有利于功能的扩展。
    3. 继承的出现让类与类之间产生了关系,提供了多态的前提。
  • 子类继承了父类,就继承了父类的方法和属性。

  • 在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和 方法。

  • 在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集, 而是对父类的“扩展”。

  • 注意:

  1. 不要仅为了获取其他类中某个功能而去继承 。
  2. 子类不能直接访问父类中私有的(private)的成员变量和方法。
  3. Java只支持单继承和多层继承,不允许多重继承 , 一个子类只能有一个父类 , 一个父类可以派生出多个子类
1
2
class SubDemo extends Demo{ } //ok 
class SubDemo extends Demo1,Demo2...//error

继承举例:

1
2
3
4
5
6
7
8
9
10
11
class Person { 
public String name;
public int age;
public Date birthDate;
public String getInfo() {
// ...
}
}
class Student extends Person {
public String school;
}

多态性(向上转型)

  • 对象的多态性:父类的引用指向子类的对象

    可以直接应用在抽象类和接口上

  • Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明 该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简 称:编译时,看左边;运行时,看右边。
    • 若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)
      多态情况下,“看左边”:看的是父类的引用(父类中不具备子类特有的方法),“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
  • 对象的多态 ——— 在Java中,子类的对象可以替代父类的对象使用
    • 一个变量只能有一种确定的数据类型
    • 一个引用类型变量可能指向(引用)多种不同类型的对象
1
2
3
Person p = new Student(); 
Object o = new Person();//Object类型的变量o,指向Person类型的对象
o = new Student(); //Object类型的变量o,指向Student类型的对象

子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。

  • 一个引用类型变量如果声明为父类的类型,但实际引用的是子类
    对象,那么该变量就不能再访问子类中添加的属性和方法
1
2
3
4
Student m = new Student();
m.school = “pku”; //合法,Student类有school成员变量
Person e = new Student();
e.school = “pku”; //非法,Person类没有school成员变量

属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编
译错误。

不能调用子类特有的方法(父类特有的方法可以调用)

多态的使用:

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
44
45
46
47
48
49
50
51
52
public class AnimalTest {
public static void main(String[] args) {
AnimalTest animaltest = new AnimalTest();
animaltest.func(new dog());
animaltest.func(new cat());

/*
* Animal animal = new dog();
* animal.eat();
* animal.shout();
*/
}
public void func(Animal animal) {
animal.eat();
animal.shout();
}
}

class Animal{
public void eat() {
System.out.println("动物,进食");
}
public void shout() {
System.out.println("动物,叫");
}
}

class dog extends Animal{
public void eat() {
System.out.println("吃狗粮");
}
public void shout() {
System.out.println("汪汪汪");
}
//狗类特有的方法
public void play(){
System.out.println("玩");
}
}

class cat extends Animal{
public void eat() {
System.out.println("吃老鼠");
}
public void shout() {
System.out.println("喵喵喵");
}
//猫类特有的方法
public void sleep() {
System.out.println("睡觉");
}
}

面试题:
多态是编译时行为还是运行时行为

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
   //面试题:多态是编译时行为还是运行时行为?
//证明如下:
class Animal {

protected void eat() {
System.out.println("animal eat food");
}
}

class Cat extends Animal {

protected void eat() {
System.out.println("cat eat fish");
}
}

class Dog extends Animal {

public void eat() {
System.out.println("Dog eat bone");

}

}

class Sheep extends Animal {


public void eat() {
System.out.println("Sheep eat grass");

}


}

public class InterviewTest {

public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}

}

public static void main(String[] args) {
int key = new Random().nextInt(3);

System.out.println(key);

Animal animal = getInstance(key);

animal.eat();

}

}

向下转型:

  • 如何才能调用子类特有的属性和方法?
    向下转型:使用强制类型转换符。
1
2
3
Animal animal = new dog();
dog d = (dog)animal;
d.play();

使用强转时,可能出现ClassCastException的异常。

1
2
3
Animal animal = new dog();
// cat d = (cat)animal;
// d.sleep();
  • 为了防止向下转型时出现ClassCastException的异常,使用instanceof关键字 。
  • a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
  • 如果 a instanceof A返回true,则 a instanceof B也返回true,其中,类B是类A的父类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  //instanceof的使用:
Animal animal = new dog();
if(animal instanceof dog){
dog d1 = (dog)animal;
d1.play();
System.out.println("====狗====");
}if(animal instanceof cat) {
cat c = (cat)animal;
c.sleep();
System.out.println("====猫====");
}if(animal instanceof Animal) {
System.out.println("====Animal====");
}if(animal instanceof Object) {
System.out.println("====Object====");
}

/*
输出:
====狗====
====Animal====
====Object====
*/

评论 (tip: 昵称框输入QQ号即可评论)

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×