Java基础学习笔记(十一)—— 继承
You got a dream, you gotta protect it.
| @Author:TTODS
java中的继承
继承是面向对象的三大特性之一:继承是类与类的一种关系,是一种“is a”的关系。比如“狗”继承“动物”,这里动物类是狗类的父类或者基类,狗类是动物类的子类或者派生类。
在java中声明类时使用 extends
关键字来指定父类,若没有指明,则默认父类为Object
,java.lang.Object
类是java的根类,java中所有类都直接或间接的继承了Object
类。
我们先创建一个Animal
类。然后再创建一个Animal
类的子类Dog
类
//创建Animal类(偷个懒,其实就是之前使用过的)
package first;
public class Animal{
String name;
float weight;
//默认的无参构造方法
public Animal() {
this.name = "暂未命名的神秘生物" ;
this.weight = 0.0f;
}
//知道名字和重量
public Animal(String n,float w) {
this.name = n;
this.weight = w;
}
//只知道重量,不知道名字
public Animal(float w) {
this("暂未命名的神秘生物",w);
}
//只知道名字,不知道重量
public Animal(String n) {
this(n,0.0f);
}
public String getName() {
return this.name;
}
public float getWeight() {
return this.weight;
}
public void sayHello() {
System.out.println("Helloooo~");
}
}
//创建一个Animal类的子类,Dog类
package first;
public class Dog extends Animal{
public String color;
public Dog() {
super();//使用父类的构造方法
this.color =null;
}
public Dog(String n,float w,String cl) {
super(n,w);//使用父类的构造方法
this.color = cl;
}
}
注意:我们在Dog
类中只写了一个成员变量color
,再看下面代码
package first;
public class Test{
public static void main(String[] args) {
Dog myDog = new Dog("小T",1.0f,"白色");
//name,weight成员变量都来自父类(Animal类)
System.out.printf("myDog: name:%S , weight:%.2fkg, color:%s\n",myDog.name,myDog.weight,myDog.color);
myDog.sayHello();//sayHello方法来自父类(Animal类)
}
}
输出
myDog: name:小T , weight:1.00kg, color:白色
Helloooo~
从上例中可以看出,虽然我们只为Dog
类写了一个成员变量color
,但是依旧可以使用从父类中继承的成员变量和方法
成员变量的隐藏和方法的覆盖
当子类中存在与父类中名字一样的成员变量时,会屏蔽父类中成员变量的名字,成为“成员变量的隐藏”。(就不演示了,看方法的覆盖,也能理解成员变量的隐藏)
当子类中存在与父类中只有方法体不同(返回值,方法名,参数列表都相同)的方法时,会将父类中的对应的方法覆盖(override)。示例:
我们再Dog
类中重写sayHello
方法:
package first;
public class Dog extends Animal{
public String color;
public Dog() {
super();//使用父类的构造方法
this.color =null;
}
public Dog(String n,float w,String cl) {
super(n,w);//使用父类的构造方法
this.color = cl;
}
//父类中已有sayHello方法,见上文
public void sayHello() {
System.out.println("Hello,我是一只小狗");
}
}
然后再执行Test.java文件:
package first;
public class Test{
public static void main(String[] args) {
Dog myDog = new Dog("小T",1.0f,"白色");
System.out.printf("myDog: name:%S , weight:%.2fkg, color:%s\n",myDog.name,myDog.weight,myDog.color);
myDog.sayHello();
}
}
输出
myDog: name:小T , weight:1.00kg, color:白色
Hello,我是一只小狗
值得注意的是,成员变量被覆盖后我们仍可以使用super
关键字指定调用父类的成员变量,方法:super.name
;
同理也可以使用super
关键字调用被覆盖的父类方法:super.sayHello()
方法覆盖时应遵循的原则
- 覆盖后的方法不能比原方法有更严格的访问控制。
- 覆盖后的方法不能比原方法产生更多的异常。