继承
面向对象程序设计语言有三大特性:封装、继承和多态性。继承是面向对象语言的重要特征之一,没有继承的语言只能被称作“使用对象的语言”。继承是非常简单而强大的设计思想,它提供了我们代码重用和程序组织的有力工具。
类是规则,用来制造对象的规则。我们不断地定义类,用定义的类制造一些对象。类定义了对象的属性和行为,就像图纸决定了房子要盖成什么样子。
比如一张图纸可以盖很多房子,它们都是相同的房子,但是坐落在不同的地方,会有不同的人住在里面。假设现在我们想盖一座新房子,和以前盖的房子很相似,但是稍微有点不同。任何一个建筑师都会拿以前盖的房子的图纸来,稍加修改,成为一张新图纸,然后盖这座新房子。所以一旦我们有了一张设计良好的图纸,我们就可以基于这张图纸设计出很多相似但不完全相同的房子的图纸来。这种基于已有的设计创造新的设计,就是面向对象程序设计中的继承。在继承中,新的类不是凭空产生的,而是基于一个已经存在的类而定义出来的。
我们把用来做基础派生其它类的那个类叫做父类、超类或者基类,而派生出来的新类叫做子类。Java用关键字extends表示这种继承/派生关系:
class ThisClass extends SuperClass{
//...
}
除了父类的构造方法是父类所独有的,子类继承得到了父类所有的成员。但是得到不等于可以随便使用。每个成员有不同的访问属性,子类继承得到了父类所有的成员,但是不同的访问属性使得子类在使用这些成员时有所不同:
当前类中 | 当前包中 | 不同包下的子类 | 其他 | |
---|---|---|---|---|
public | ok | ok | ok | ok |
protected | ok | ok | ok | |
缺省 | ok | ok | ||
privated | ok |
多态
多态变量
-java的对象变量是多态的,它们能保存不止一种类型的对象(变量拥有一个声明类型和一个动态类型)
-它们可以保存的是声明类型的对象,或声明类型的子类的对象
-当把子类的对象赋给父类的变量的时候,就发生了向上造型
造型cast
-子类的对象可以赋值给父类的变量
(对象变量的赋值并不是拿一个对象去给另一个对象赋值,而是让这两个对象的管理者去管理一个共同的对象)
-父类的对象不能赋值给子类的变量!
Vechicle v;
Car c = new Car();
v = c; //可以
c = v; 编译错误!!!
-可以用造型:
c = (Car) v;
(只有当v这个变量实际管理的是Car才行)
重写(Override)
当父类的方法不能满足子类的需要,这时子类可以重写父类的方法;即子类讲从父类继承的方法重新写方法体,我们叫做方法的重写。
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
代码实例:
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}
以上实例编译运行结果如下:
动物可以移动
狗可以跑和走
重写的要求:1、必须要有继承关系;2、方法声明必须保持一致(参数列表必须完全与被重写方法的相同;返回类型必须完全与被重写方法的返回类型相同;但访问权限可以扩大)3、构造函数不能被重写4、静态方法不能被重写
重写的自动转型:子类对象可以自动的变为父类对象。自动转型后调用重写的方法,以子类方法为准。
Super关键字的使用
当需要在子类中调用父类的被重写方法时,要使用super关键字。
代码实例:
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog 对象
b.move(); //执行 Dog类的方法
}
}
以上实例编译运行结果如下:
动物可以移动
狗可以跑和走
其中super主要有两种用法:
①super.成员变量/super.成员方法;
②super(parameter1,parameter2…)
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器,要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。
重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。