现在我们要写一个狗类,也要写一个猫类:
package oop1;
public class Dog {
public String name;
public int age;
public String color;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
package oop1;
public class Cat {
public String name;
public int age;
public String color;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
可以发现,猫类和狗类中属性和方法是一样的,看下来代码几乎是一样的,但是我们还得写两遍,这就很麻烦,虽然可以复制粘贴,但是当后续又有猪、猴、马、兔呢?所以我们想要类似于一个模板一样的东西。在Java中我们可以使用继承。
1.什么是继承?
Java中将多个类中具有的相同属性和方法抽取出来,写到一个单独的类中,将这个类作为父类,这里就涉及到了继承的概念,其它的类使用这个类去生成新的类,就叫继承了这个类,这个类就是父类,继承父类的其它类就作为该父类的子类。
父类也叫基类、超类。子类也可叫做派生类。
我们将上述猫、狗类中的属性和方法抽取出来,放到一个Pet类中,Dog、Cat类继承Pet:
继承的关键字:extends
语法:子类 extends 父类
Pet:
package oop1;
public class Pet {
public String name;
public int age;
public String color;
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
}
Dog:继承Pet类
public class Dog extends Pet{
}
Cat:继承Pet类
public class Cat extends Pet{
}
如果我们再多几个动物类,也可以继承Pet类,这样是不是就减少了很多的代码量呢?继承的好处就是:代码重用。
2.继承的使用
(1)子类拥有了父类的哪些东西?
那继承了父类有什么用呢?我们就可以使用父类的属性和方法了。
我们在Dog类中new一个对象,使用.来查看一下有没有什么:
我们可以看到,Dog类的对象拥有了父类的全部属性和方法。
package oop1;
public class Dog extends Pet{
public static void main(String[] args) {
//使用父类属性
Dog dog = new Dog();
dog.name = "哈士奇";
dog.age = 3;
dog.color = "黑";
System.out.println(dog.name+"\t"+dog.age+"\t"+dog.color);
//调用父类方法
dog.eat();
dog.sleep();
}
}
运行也是没有问题的:
这就像儿子可以使用父亲的很多东西一样,但是儿子可以使用父亲的所有东西吗?这肯定是不可以的,那继承的东西是否也会有限制呢?我们再来看看四个权限修饰符的权限表:
在学了父类、子类概念后,现在我们已经可以看明白整个表了。可以看到,private修饰的就算是同一个包下的子类都是不可访问的,我们来实验一下,将属性修改成四个不同权限修饰符修饰:
package oop1;
public class Pet {
public String name;
protected int age;
String color;
private double price;
public void eat(){
System.out.println("吃饭");
}
protected void walk(){
System.out.println("散步");
}
void play(){
System.out.println("玩耍");
}
private void sleep(){
System.out.println("睡觉");
}
}
再验证一下不同包下的子类:
验证结果与表中一致,所以得出结论:同一包下的子类,继承父类之后,就拥有了父类中除私有的属性和方法;不同包下的子类,继承父类之后,就拥有了除私有的和默认的以外的私有属性和方法。
(2)子类能否继承父类的构造方法?
我们说子类可以继承父类的符合权限的属性和方法,那我们知道构造方法是特殊的方法,父类的构造方法能否被子类继承呢?
构造方法是用来创建唯一的东西的,如果子类继承了父类的构造方法,则在创建对象时就不知道创建的是父对象还是子对象,调用父类的构造方法,不会创建一个父对象,只是初始化父类的成员属性和方法(因为子类继承父类后,会获取到父类的属性和方法,这些属性和方法在使用前必须先初始化,所以须先调用父类的构造器进行初始化)。
也不会产生父类对象,只是用了父类的构造方法而已,并不是用到构造方法就会产生对象,构造方法只是起对象初始化作用的,而不是起产生对象作用的;即只有 new 语句才会产生父类的对象。
所以,子类不会继承父类的构造方法,但是会调用父类的构造方法用于初始化。
package oop1;
public class Pet {
public Pet() {
System.out.println("我是父类的构造方法");
}
}
package oop1;
public class Cat extends Pet{
public Cat() {
System.out.println("我是子类的构造方法");
}
public static void main(String[] args) {
Cat cat = new Cat();
}
}
这里看到虽然输出了父类的构造方法中的输出语句,但是只是子类在new对象时调用了父类的构造方法而已。这是一个很容易混淆和绕晕自己的点。
扩展:
可以从结果中看出,在子类中new对象,是先输出了父类的构造方法中的内容,再输出了子类构造方法中的内容,这里涉及到了:
继承关系的初始化顺序:
父类的属性
父类的构造方法
子类的属性
子类的构造方法
(3)能否继承多个类?
既然继承那么好用,我们可不可以多继承几个类呢?
是不可以的,提示中写着类不能继承多个类,所以Java是单继承,只能直接的继承一个类。
(4)继承了父类之后还能不能有自己的属性和方法?
子类继承了父类之后,还能不能定义自己的属性和方法呢?
Pet:父类
package oop1;
public class Pet {
public String name;
public int age;
public String color;
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
Cat:子类
package oop1;
public class Cat extends Pet{
public double price;
public void play(){
System.out.println("猫抓老鼠");
}
public static void main(String[] args) {
Cat cat = new Cat();
//继承父类属性
cat.name = "肥橘";
//子类自定义属性
cat.price = 1000;
//继承父类方法
cat.eat();
//子类自定义方法
cat.play();
}
}
子类继承了父类具有权限的属性和方法之后,也可以自定义独有的属性和方法。
3.总结
- 同一包下的子类,继承父类的除私有的以外的属性和方法;
- 不同包下的子类,继承父类的除私有的和默认的以外的属性和方法;
- 子类不继承父类的构造方法;
- 单继承,只能直接继承一个类;
- 继承父类之后,子类还能自定义属性和方法。
本人水平有限,若有错误,望指出~