封装性,继承性和多态性
封装性
我们程序设计追求“高内聚,低耦合”。
高内聚 :类的内部数据操作细节自己完成,不允许外部干涉
低耦合 :仅对外暴露少量的方法用于使用
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提 高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露 的暴露出来。这就是封装性的设计思想。
Java中通过将数据声明为私有的(private),再提供公共的(public) 方法:getXxx()和setXxx() 实现对该属性的操作,以实现下述目的:
隐藏一个类中不需要对外提供的实现细节;
使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑, 限制对属性的不合理操作;
便于修改,增强代码的可维护性;
继承性
为什么要有继承?
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行为,只要继承那个类即可。
此处的多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。
类继承语法规则: class Subclass extends SuperClass{ }
继承的作用:
继承的出现减少了代码冗余,提高了代码的复用性。
继承的出现,更有利于功能的扩展。
继承的出现让类与类之间产生了关系,提供了多态的前提。
子类继承了父类,就继承了父类的方法和属性。
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和 方法。
在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集, 而是对父类的“扩展”。
注意:
不要仅为了获取其他类中某个功能而去继承 。
子类不能直接访问父类中私有的(private)的成员变量和方法。
Java只支持单继承和多层继承,不允许多重继承 , 一个子类只能有一个父类 , 一个父类可以派生出多个子类
1 2 class SubDemo extends Demo { } 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(); o = new Student();
子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。
一个引用类型变量如果声明为父类的类型,但实际引用的是子类 对象,那么该变量就不能再访问子类中添加的属性和方法
1 2 3 4 Student m = new Student(); m.school = “pku”; Person e = new Student(); e.school = “pku”;
属性是在编译时确定的,编译时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()); } 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();
为了防止向下转型时出现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 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====" ); }
评论区