Java继承
目录
1.继承的定义
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的作用:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。
相关代码:
class test1{
public static void main(String[] args){
test3 new1 = new test3();//调用子类
new1.name="小胖";
new1.age=20;
new1.show();
}
}
class test2{
//父类
String name;
int age;
public void show(){
System.out.println(name);
System.out.println(age);
}
}
class test3 extends test2{
//子类继承了父类
}
最后输出:
小胖
20
2.继承的好处
继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
可以在子类中声明一个在父类中没有的新字段和方法;
可以在子类中编写一个父类当中具有相同名的新实例方法,这称为**“方法重写”或“方法覆盖”;
可以在子类中编写一个调用父类构造方法的子类构造方法**,既可以隐式地实现,也可以通过使用关键字super来实现。
但是要注意:
Java只支持单继承不支持多继承
即:Java中可以有多个子类继承1个父类但是1个子类不能继承多个父类。
3.this与super
3.1super的作用
super:代表对当前对象父类的引用
3.11super调用成员变量
代码
public class test1{
//父类
String name = "小胖";
int age = 20;
}
public class test2 extends test1{
//子类
int age = 19;
public void show(){
System.out.println(name);
System.out.println(age);
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();
in1.show();
}
}
最后输出
小胖
19
而这个
public class test1{
//父类
String name = "小胖";
int age = 20;
}
public class test2 extends test1{
//子类
int age = 19;
public void show(){
System.out.println(super.name);
System.out.println(super.age);
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();
in1.show();
}
}
最后输出
小胖
20
用super会调用父类的成员变量
注意:
在构造方法的过程中
如果没有写this或super,则会在构造方法的最上端自动加上一个super();
这个是super调用成员变量的结果
那么super调用构造方法呢
3.12super调用构造方法
看代码
public class test1{//父类
private String name;
private int age;
public test1(){
System.out.println("父类的无参构造");
}
public test1(String name,int age){
this.name=name;
this.age=age;
System.out.println("父类的有参构造");
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
public class test2 extends test1{//子类
public test2(){
super("渊酱",19);//调用父类中的构造方法
System.out.println("子类的无参构造");
}
public test2(String name,int age){
super(name,age);
System.out.println("子类的有参构造");
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();//无参构造
in1.setName("渊酱");
in1.setAge(19);
System.out.println(in1.getName()+in1.getAge());
System.out.println("------------------");
test2 in2 = new test2("小胖",20);//有参构造
System.out.println(in2.getName()+in2.getAge());
}
}
最后输出
父类的有参构造
子类的无参构造
渊酱19
------------------
父类的有参构造
子类的有参构造
小胖20
这个比较简单,无需解释
如果无参构造过程中没有加super(“渊酱”,19)
最后输出
父类的无参构造
子类的无参构造
渊酱19
------------------
父类的有参构造
子类的有参构造
小胖20
3.13super调用成员方法
代码
public void test1{
public void show(){
System.out.println("父类");
}
}
public void test2 extends test1{
public void show(){
super.show();
System.out.println("子类");
}
}
public void test3{
public static void main(String[] args){
test2 in1 =new test2();
super.in1.show();
}
}
最后输出
父类
子类
而如果去掉super.show()
则输出
子类
3.2this的作用
this:代表当前对象的引用,谁来调用我,我就代表谁
3.21this调用成员变量
public class test1{
//父类
String name = "小胖";
int age = 20;
}
public class test2 extends test1{
//子类
int age = 19;//就近原则,子类有了就不用父类了
public void show(){
System.out.println(this.name);
System.out.println(this.age);
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();
in1.show();
}
}
最后输出:
小胖
19
而这个
public class test1{
//父类
String name = "小胖";
int age = 20;
}
public class test2 extends test1{
//子类
int age = 19;
public void show(){
System.out.println(super.name);
System.out.println(super.age);
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();
in1.show();
}
}
最后输出
小胖
20
注意:最后输出年龄的时候输出的是子类中的年龄,而非父类中的年龄。
当子类有了相应的成员变量就不需调用父类的成员变量。
而当子类没有相对应的成员变量,便用父类已有的成员变量。
这个是this调用成员变量的结果
那么this调用构造方法呢
3.22this调用构造方法
看代码
public class test1{//父类
private String name;
private int age;
public test1(){
System.out.println("父类的无参构造");
}
public test1(String name,int age){
this.name=name;
this.age=age;
System.out.println("父类的有参构造");
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
public class test2 extends test1{//子类
public test2(){
this("渊酱",19);//调用本类中的构造方法
System.out.println("子类的无参构造");
}
public test2(String name,int age){
super(name,age);
System.out.println("子类的有参构造");
}
}
public class test3{
public static void main(String[] args){
test2 in1 = new test2();//无参构造
in1.setName("渊酱");
in1.setAge(19);
System.out.println(in1.getName()+in1.getAge());
System.out.println("------------------");
test2 in2 = new test2("小胖",20);//有参构造
System.out.println(in2.getName()+in2.getAge());
}
}
最后输出
父类的有参构造
子类的有参构造
子类的无参构造
渊酱19
------------------
父类的有参构造
子类的有参构造
小胖20
无参构造时,在子类的无参构造方法时,因为有this(“渊酱”,19);调用本类的构造方法,就相当于走了子类有参构造
的构造方法
之后将name=“渊酱”,age=19传入父类的有参构造
于是输出:父类的有参构造
然后继续进行子类的有参构造输出:子类的有参构造
这步走完后接着进行之前子类无参构造的步骤
输出:子类的无参构造
经历in1.setName(“渊酱”);
in1.setAge(19);
于是输出:渊酱19
再输出**------------------**
下一步是有参构造了
很容易写出后面:
父类的有参构造
子类的有参构造
小胖20
如果无参构造过程中没有加this
则最后输出
父类的无参构造
子类的无参构造
渊酱19
------------------
父类的有参构造
子类的有参构造
小胖20
3.23this调用成员方法
在一个类的内部,成员方法之间的互相调用时也可以使用“this.方法名(参数)”来进行引用,只是所有这样的引用中this都可以省略,所以这里就不详细介绍了。
3.3this与super的区别
1.this与super分别代表什么
[1]this代表对当前对象的引用,谁来调用我,我就代表谁
[2]super代表对对象父类的引用
2.this与super的使用区别
[1]调用成员变量
this.成员变量 既可以调用本类的成员变量也可以调用父类的
super.成员变量 只可以调用父类的
[2]调用构造方法
this(…)使用本类的构造方法
super(…)使用父类的构造方法
[3]调用成员变量
this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
super.成员变量 调用父类的成员变量
4.继承中的经典题目(用到了继承和代码块的知识)
运行结果并解释:
public static void main( String [] args) {
Zi z = new Zi();
}
}
class Fu {
static {
System.out.println( "静态代码块Fu" );
}
{
System.out.println( "构造代码块Fu" );
}
public Fu() {
System.out.println( "构造方法Fu" );
}
}
class Zi extends Fu {
static {
System.out.println( "静态代码块Zi" );
}
{
System.out.println( "构造代码块Zi" );
}
public Zi() {
System.out.println( "构造方法Zi" );
}
静态代码块Fu
静态代码块Zi
构造代码块Fu
构造方法Fu
构造代码块Zi
构造方法Zi
1,jvm调用了main方法,main进栈
2,遇到Zi z = new Zi();会先将Fu.class和Zi.class分别加载进内存,再创建对象,当Fu.class加载进内存
父类的静态代码块会随着Fu.class一起加载,当Zi.class加载进内存,子类的静态代码块会随着Zi.class一起加载
第一个输出,静态代码块Fu,第二个输出静态代码块Zi
3,走Zi类的构造方法,因为java中是分层初始化的,先初始化父类,再初始化子类,所以先走的父类构造,但是在执行
父类构造时,发现父类有构造代码块,构造代码块是优先于构造方法执行的所以
第三个输出构造代码块Fu,第四个输出构造方法Fu
4,Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,构造方法Zi