继承、封装、多态
在java语言中的三大特性: 继承、封装、多态
1,封装
封装顾名思义就是封锁装起来的意思。也就是将一些实现细节隐藏起来。就像电脑,我们只用轻轻松松的敲敲键盘就可以实现一些功能,然而对于这背后是如何工作的却不知这就是封装。
封装需要使用关键字private
//对person类中的属性进行封装 只能本类可以访问
public class Person {
private String name;
private int age;
}
如果外部想要访问并进行修改需要使用一些公共方法。如:getXXX,setXXX方法
//使用this关键字进行相关实例化
public class Person{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
封装的优点
- 良好的封装能够减少耦合。
- 类内部的结构可以自由修改。
- 可以对成员变量进行更精确的控制。
- 隐藏信息,实现细节。
2,继承
继承现实中的意义就是,你继承了家里的亿万家产而这个继承是你从你父亲那里得来到。然而就比如你的父亲不止你一个孩子,你还有兄弟姐妹他们和你一样继承父亲的财产以及相关属性
继承需要用到关键字:extends
继承的格式
class 父类 {
}
class 子类 extends 父类 {
}
为什么要继承?
因为共同的有许多属性相同导致代码重复,代码量大且臃肿不易于维护所以提取出一个父类可以使得代码简洁提高代码的复用性和维护性
注意
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承不可进行多继承:(即一个类只能有一个父类不可以继承多个父类),但是可以多重继承,单继承就是一个子类只能继承一个父类,然而多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承时的注意事项
子类只能继承父类所有非私有的成员(成员方法和成员变量)
子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
子类在执行构造方法时,默认第一行调用父类的无参构造方法先执行super();
不要为了部分功能而去继承
切记:先父后子,先有父亲的子类才可以继承
this与super的区别
this : 代表的是本类对象的引用
super : 代表的是父类的引用
关键字:final
final意思为终结的,可以用来定义常量,修饰类,方法,变量等。
final 修饰变量,此变量就为一个常量
final修饰类,此类不能被继承
final 修饰方法,此方法不能被重写。
注意
final可以修饰基本数据类型也可以修饰引用数据类型
final修饰基本数据类型,指的是这个值不能被改变。
final修饰引用数据类型, 指的是这个地址值,不能再次被改变
注意区分重载和重写
3,多态
多态的概述
对象在不同时刻表现出的不同状态。
多态的前提
-
要有继承或者实现的关系
-
要有方法的重写(必须有继承前提)
-
要有父类引用指向子类对象
即: 父类 父类引用名 = new 子类();
父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
class Animal { public void shout() { System.out.println("叫了一声!"); } } class Dog extends Animal { public void shout() { System.out.println("旺旺旺!"); } public void seeDoor() { System.out.println("看门中...."); } } class Cat extends Animal { public void shout() { System.out.println("喵喵喵喵!"); } } public class TestPolym { public static void main(String[] args) { Animal a = new Cat(); // 向上可以自动转型 //传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。 animalCry(a); Animal a2 = new Dog(); animalCry(a2);//a2为编译类型,Dog对象才是运行时类型。 即编译看左边执行看右边 // a2.seeDoor();//编译错误,无法调用子类独有的方法 //编写程序时,如果想调用运行时类型的方法,只能进行强制类型转换。 // 否则通不过编译器的检查。 Dog dog = (Dog)a2;//向下需要强制类型转换 } // 有了多态,只需要让增加的这个类继承Animal类就可以了。 public static void animalCry(Animal a) { a.shout(); } /* 如果没有多态,我们这里需要写很多重载的方法才可以实现。 public static void animalCry(Dog d) { d.shout(); } public static void animalCry(Cat c) { c.shout(); } */ }
好处
提高了代码的维护性(继承保证)
提高了代码的扩展性(由多态保证)坏处
不可以使用子类特有的方法,但可以通过将父类强制转换为子类解决(向下转型)
多态的成员访问特点
多态访问成员变量:编译看左边,执行看左边
多态访问构造方法:创建子类对象的时候,会先访问父类的构造方法,对父类的数据进行初始化
多态访问成员方法:编译看左边,执行看右边
静态和类相关,算不上重写,所以,执行还是左边的
多态的内存图