Java中的继承
一、关于继承的基本了解
1.什么是继承?
概念:定义有两个类,一个类作为子类,另一个类作为父类,由子类继承父类中的成员属性和成员方法,当然,子类中也可以有属于自己专有的成员属性和成员方法。
2.为什么要继承?
Java中专门用来进行共性抽取,实现代码复用(即将几个类的共性抽取出来,放进父类中,如果这几个类想访问这些共性就可以继承本父类,从而达到代码复用的过程,不用再多此一举去重复写代码了)。
3.继承的语法
Demo:
class A {
//关于A的一些属性和方法
}
class B extends A {
//B中特有的一些属性和方法
}
举例:猫和狗都是动物,都有名字和年龄,也有自己特殊的属性和行为。
class Animal {
//猫和狗共有的属性
public String name;
public int age;
//猫和狗共有的行为
public void eat() {
System.out.println("正在吃饭!");
}
}
class Dog extends Animal {
public boolean silly;//狗特有的属性,傻
//狗特有的行为
public void guard() {
System.out.println("正在看家护院!");
}
}
class Cat extends Animal {
//猫特有的属性
//猫特有的行为
public void catchMouse() {
System.out.println("正在抓老鼠!");
}
}
4.注意事项
- 子类继承父类后,就会把父类中的属性和方法都继承下来。
- 子类也叫派生类,父类也叫基类或者超类。
- 子类继承父类之后,必须要新添自己特有的成员属性或者成员方法,体现出与父类的不同,否则就没有必要继承。
二、访问父类成员
由于在子类中继承了父类的属性和方法,但是咱们该如何去使用这些属性和方法呢?
1.子类访问父类中的成员变量
(1)访问子类和父类中存在同名的变量
Demo:
class A {
public int a = 1;
public String name = "hello";
}
class B extends A {
public int a = 2;
public void func() {
System.out.println(a);
}
}
public class TestDemo {
public static void main(String[] args) {
B b = new B();
b.func();
}
}
//执行结果:
2
可以从代码的结果看出,如果子类和父类中有同名的变量时,在子类中访问此同名变量,会变成访问子类的那个变量。
(2)访问子类和父类不同名的变量
Demo:
class A {
public int a = 1;
public float f = 1.2f;
}
class B extends A {
public int a = 2;
public void func() {
System.out.println(f);
}
}
public class TestDemo {
public static void main(String[] args) {
B b = new B();
b.func();
}
}
//执行结果:
1.2
可以从代码的结果看出,子类是直接访问从父类继承下来的变量.
如果父类中也没有此变量的话,编译就会报错.
(3)总结
-
在子类方法或由子类创建的对象访问成员时,如果访问的成员变量在子类中有,优先访问子类中的那个变量.
-
如果访问的成员变量,在子类中不存在,则访问父类中继承下来的成员变量,如果父类中也不存在,则编译报错.
-
私有的成员变量,可以被继承,但是不能被访问.
2.子类访问父类中的成员方法
(1)子类和父类的方法同名时
Demo:
class A {
public void funcA() {
System.out.println("A中的funcA()");
}
}
class B extends A {
public void funcA() {
System.out.println("B中的funcA()");
}
public void funcB() {
funcA();
}
}
public class TestDemo {
public static void main(String[] args) {
B b = new B();
b.funcB();
}
}
//执行结果:
B中的funcA()
可以从代码中看了出,当子类和父类中有同名的方法,然后在子类另一个方法中访问这个方法时,会优先访问子类中的那个方法。
(2)子类和父类中的方法不同名时
Demo:
class A {
public void funcA() {
System.out.println("A中的funcA()");
}
}
class B extends A {
public void funcB() {
funcA();
}
}
public class TestDemo {
public static void main(String[] args) {
B b = new B();
b.funcB();
b.funcD();
}
}
//执行结果:
A中的funcA()
编译报错,因为子类和父类中均没有funcD()
可以从执行结果中看出,当子类和父类成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。
三、super关键字
1.什么是super关键字?
在java中,super表示超类(就是我们俗称的父类),当子类需要引用父类的属性或者方法时,我们就可以使用super.FieldName.
2.如何使用super关键字?
(1)使用super+“.”,访问父类中的普通成员.
Demo:
class Animal {
public String name ;
public int age;
public void eat() {
System.out.println("正在吃饭!");
}
}
class Dog extends Animal {
public boolean silly;
public void guard() {
System.out.println(name+"正在看家护院!");
}
public void func() {
super.name = "小黑";
guard();
}
}
class Cat extends Animal {
public void catchMouse() {
System.out.println("正在抓老鼠!");
}
}
public class TestDemo {
public static void main(String[] args) {
Dog dog =new Dog();
dog.func();
}
}
//执行结果:
小黑正在看家护院!
(2)使用suepr+“.”+方法名,调用父类中的普通成员方法.
Demo:
class Animal {
public String name ;
public int age;
public void eat() {
System.out.println(name+"正在吃饭!");
}
}
class Dog extends Animal {
public boolean silly;
public void guard() {
System.out.println(name+"正在看家护院!");
}
public void func() {
super.name = "小黑";
super.eat();
}
}
class Cat extends Animal {
public void catchMouse() {
System.out.println("正在抓老鼠!");
}
}
public class TestDemo {
public static void main(String[] args) {
Dog dog =new Dog();
dog.func();
}
}
//执行结果:
小黑正在吃饭!
(3)super+( ),调用父类中的构造方法.
class Animal {
public String name ;
public int age;
public void eat() {
System.out.println("正在吃饭!");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal {
public boolean silly;
public void guard() {
System.out.println(name+"正在看家护院!");
}
public Dog(String name,int age,boolean silly) {
super(name,age);
this.silly = silly;
}
}
class Cat extends Animal {
public void catchMouse() {
System.out.println("正在抓老鼠!");
}
public Cat(String name,int age) {
super(name,age);
}
}
public class TestDemo {
public static void main(String[] args) {
Dog dog = new Dog("小黑",5,false);
dog.guard();
}
}
//执行结果:
小黑正在看家护院!
注:
- 在子类完成构造方法之前,先帮助父类部分初识化,在这里即name和age的初始化.
- super()必须是构造方法中的第一条语句.
四、super关键字和this关键字的区别
1.相同点
(1)都是Java中的关键字.
(2)都只能在类的非静态方法中使用,用来访问非静态成员变量或者方法.
(3)在构造方法中调用时,都必须是构造方法中的第一条语句,且不能同时存在.
2.不同点
(1)this是当前对象的引用(当前对象即调用实例方法的对象),而super相当于是子类对象对从父类继承下来部分成员的引用.
(2)在非静态成员方法中,this用来访问本类的方法和属性,而super用来访问父类继承下来的方法和属性.
(3)在构造方法中,this( )用来调用本类构造方法,而super( )用来调用父类构造方法,两种调用不能同时在构造方法中出现.
(4)构造方法中一定会存在super( )的调用,即使用户没有写,编译器也会自动生成,但this( )用户没有写,则没有生成.
class Animal {
public Animal() {
}
}
class Dog extends Animal {
//即使用户自己没有写,也会有此生成
public Dog() {
super();//调用父类的构造方法
}
}
五、继承的方式
1.单继承
就是一个类继承另一个类,此方法比较简单.
Demo:
class A {
}
class B extends A {
}
2.多层继承
就是一个类A继承类B,然后类B再继承类C,从关系看出,类A也能继承类C中的成员属性或者方法.
Demo:
class C {
}
class B extends C {
}
class A extends B {
}
3.注意事项
(1)Java中不支持一个类被多个类继承
(2)Java中也不支持一个类继承多个类
六、继承和组合
和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是is-a的关系.
组合表示对象之间是has-a的关系.
Demo:老师和学生都是属于学校的一部分
class Student {
}
class Teacher {
}
class School {
public Student[] students;
public Teacher[] teachers;
}
好啦!本期的博客就到此结束了,如果各位小伙伴们有什么问题或者我有什么写错的地方,请提出来哦!