目录
1.为什么要有继承
例如我们想要去写两个类,一个Dog 和一个Cat 类.
public class Dog {
public String name;
public int age;
public void eat() {
System.out.println("吃东西");
}
}
public class Cat {
public String name;
public int age;
public void eat() {
System.out.println("吃东西");
}
}
我们可以看到两个类中有相同的成员变量名字和年龄,还有一个相同的方法。代码出现了大量的重复,这样写不是很好。于是java中就提出了继承的概念。减少了大量重复的代码.
2.继承的语法
java中继承的关键字是 extends 例如我们有一个Animal的类
语法是 修饰符 class 子类名字 extends 父类名字
public class Animal {
public String name;
public int age;
public void eat() {
System.out.println("吃东西");
}
}
我们就可以使用extends关键字去创建一个Dog的类去继承Animal
public class Dog extends Animal {
public void brak() { System.out.println("叫"); }}lr
这样我们Dog就继承了Animal的成员变量和方法。我们可以创建一个对象,通过调试去看虽然我们的Dog类中没有创建成员变量但是我们的dog中仍然有name和age
也可以访问父类中的方法
在继承中还有一些名字的关系例如子类也可叫派⽣类,父类可以叫基类或超类。
在创建子类对象的时候一定要体现出对于父类的不同点否则这样的子类是没有意义的
3.成员变量和方法的访问
1.父类和子类没有相同的名字
class Animal {
public int a = 1;
public int b = 2;
public void method1() {
System.out.println("ssssss");
}
}
class Dog extends Animal{
public int c = 3;
public void method2() {
System.out.println("a " + a);
System.out.println("b " + b);
System.out.println("c " + c);
}
}
我们可以创建对象来调用这个方法看一下
我们可以看到是可以正常调用父类的成员变量的在不同名的情况下,方法也是一样。也可以正常的访问。
2.父类和子类有相同的名字
class Animal {
public int a = 1;
public int c = 2;
public void method() {
System.out.println("ssssss");
}
}
class Dog extends Animal{
public int c = 3;
public void method() {
System.out.println("a " + a);
System.out.println("c " + c);
}
}
这个时候我们看到子类和父类中有两个名字相同的方法,这个时候如果我们创建子类对象访问method的方法的时候是访问子类的method方法是访问不到父类的method的方法的。
成员变量也是一样如果子类和父类同名,同过子类对象是访问不到父类的成员变量的。
继承中成员变量的访问:如果父类和子类同名就近原则,优先访问子类自己的方法。如果,不同名,优先在子类中找,如果子类中没有就去父类中去找。
4.super关键字
我们上面提到了,如果子类和父类中有同名的成员变量和方法,通过子类对象只能方法到子类自己的。那么我们如何去访问到父类自己的方法呢?这里java中就提出了super关键字。通过super关键字去访问父类的成员变量和方法。
class Animal {
public int a = 1;
public int c = 2;
public void method() {
System.out.println("ssssss");
}
}
class Dog extends Animal{
public int c = 3;
public void method() {
System.out.println("子类 c " + c);
System.out.println("父类 c " + super.c);
}
}
我们可以看一下结果。
super加点号加父类成员变量名,可以访问到父类的成员变量,例如这个例子通过 super.c 可以访问到父类的成员变量。同名成员方法也可以这样去访问,例如super.method() 可以去访问到父类的method方法。
class Animal {
public String name;
public int age;
public void sleep() {
System.out.println("睡觉");
}
}
class Dog extends Animal{
public String color;
}
这个时候我们可以看一下这个代码的内存是怎么样的
5.类的构造方法
构造方法是对类的成员进行初始化,那么为什么我们上面的例子没有写父类和子类的构造方法为什么没有报错?因为构造方法在没有写的时候,编译器会自到生成一个不带参数的构造方法。如果我们写个构造方法编译器就不会在自己生成。
class Animal {
public Animal(int a) {
System.out.println("sssss");
}
}
class Dog extends Animal{
public Dog() {
}
}
我们可以看一下这个代码为什么我们写了构造方法但是我们在运行时候的编译器仍然会报错?
这是因为我们要先有父类才可以有子类,所以我们必须先去完成父类的构造方法。这个时候我们就又要用到super关键字了。同过super可以完成父类的构造方法。
class Dog extends Animal{
public Dog() {
super(10);
}
}
这个时候编译器就不会报错了。用super完成父类的构造方法必须要放在第一行否则编译器会报错