本期来详细的讲一下继承!
首先我们先创建两个类 一个类我们命名为 Student 一个命名为 People
public class People { private String name; private int age; public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } }
之后我们尝试调用一下people里面的各个方法
public static void main(String[] args) { People people = new People(); people.setAge(18); System.out.println( people.getName() + " "+ people.getAge()); } John 18 进程已结束,退出代码为 0
运行结果一切正常。
那么我们下一步就可以去尝试将people继承到student 通过 extend关键字
public class Student extends Person { }
写成这样,我们尝试调用student试试?
public static void main(String[] args) { People people = new People(); people.setName("Joh22"); people.setAge(18); System.out.println( people.getName() + " "+ people.getAge()); Student student = new Student(); student.setAge(18); student.setName("John"); System.out.println( student.getName() + " "+ student.getAge()); } 运行结果: Joh22 18 John 18 进程已结束,退出代码为 0
好的我们以及大体掌握的继承的用法!
那么下一步我们来进行一些更深入的操作!
我们新建两个类一个为parent 一个为 child
在parent和child分别写一个方法命名为test
public static void test(){ System.out.println("Child"); }
这是在child中的代码,parent则将里面输出的文本改为Parent
像前文一样我们使child继承parent
public class Child extends Parent { public static void test(){ System.out.println("Child"); } }
这时候我们尝试用另一种方式调用
public static void main(String[] args) { Child child = new Child(); child.test(); Parent parent = new Child(); parent.test(); }
大家猜一猜它的输出是什么?
你可能会想,唉?parent被赋值了new child 那么它的调用结果应该输出child啊?但是它的类型却是Parent?什么情况?
在开始将之前我先将结果说出来
Child Parent 进程已结束,退出代码为 0
这就是结果,和你想的一样吗?
那么为什么?明明它被定义为Child却还是输出了Parent? 如果你仔细看一下代码你就会发现,在Child和Parent中有一个关键字 static 这意味着它们将是静态的方法。
我们知道静态方法可以通过类名直接调用,而不需要创建类的实例,所以如果你真的动手去写了那么你的编译器肯定会输出一个警告
所以说其实正确的调用是
Child.test(); Parent.test();
这样也就解释了输出的结果为什么和我们前文中说的有出入了。
当你创建一个对象时,它的实际类型是由new
关键字后面的类决定的。但是在static关键字修饰下方法为静态方法,在调用静态方法时,由引用类型决定调用哪个方法而不是实际对象类型。
所以说在前文中你的对象类型虽然是Child,但是它的引用类型为parent,导致了输出结果的变化。
解决方法就是删除掉static关键字即可。那么这也就引申出来了一个新的概念,方法的重写。
如果你使用的是idea,那么你可以按下alt+ins键去打开一个悬浮窗,点击里面的方法重写,或者直接按下CTRL+O 打开方法重写的窗口。
选择要重写的方法,点击确定。
public class Child extends Parent { @Override public void test() { super.test(); } }
我们得到了一个新的代码,其中有两个较为陌生 一个是@Override 一个是super
其中@Override 你可以理解为高级注释,一个带有功能的注释,我们不细讲。
我们来讲解一下super。
super
关键字用于访问父类的成员
例如我们简单的写一个代码
class Parent { int x = 10; } class Child extends Parent { int x = 20; void display() { System.out.println(super.x); // 访问父类的x变量,输出10 System.out.println(this.x); // 访问子类的x变量,输出20 } }
这样我们直观的看出来了,super访问的是父类,而其中又有一个陌生的关键字,this,它则代表着访问自身,这一点也可以在前文中的代码中看出来。
super可以访问父类中的方法,变量,还可以访问父类的构造函数。
回到前文,我们重写了那个方法,那么我们再次调用一下试试?
这时候结果便变成的两个Child,但其实这并不是因为方法重写,而是因为我们删除了static关键字的原因。
那么聪明的你会问了,方法的重写有什么用?
它可以扩大方法的范围,我可以简单的举一个例子。
我们将父类中方法的public改为protected
这时候我们重写方法,将子类中的protected改为public,这时候调用子类中那个方法其实也调用的父类的,但是由于子类中的为public,所以说我们其实变相的扩大了父类中方法的范围。
(☆ω☆)
3