1. 继承
1.1 为什么要继承
在Java中我们定义猫类和狗类,如下
public class Cat {public String name;public int age;public String color;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}public void bark(){System.out.println(name + "在喵喵叫");}
}
public class Dog {public String name;public int age;public String color;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}public void bark(){System.out.println(name + "在汪汪叫");}
}
根据图片我们可以发现猫类和狗类有大量重复的代码,我框住的就是重复的地方。
在Java中,于是就提出了继承这个概念,用来抽取共性。
1.2 继承的概念
在Java中,继承是面向对象编程的重要特性之一,它允许一个类(子类)继承另一个类(超类)的属性和方法。通过继承,子类可以重用超类的代码,从而提高代码的可重用性和可维护性,即实现共性的抽取,代码复用。
上述代码中,猫和狗都是动物,我们可以定义一个动物类将共性抽取,再让猫类和狗类都继承这个动物类实现代码复用
1.3 如何继承
继承需要用到 extends关键字
修饰符 class 子类 extends 父类 {// ...
}
将上述代码用继承实现
public class Animal {public String name;public int age;public String color;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}
}public class Cat extends Animal {public void bark(){System.out.println(name + "在喵喵叫");}
}public class Dog extends Animal{public void bark(){System.out.println(name + "在汪汪叫");}
}
子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了
1.4 父类成员的访问
那么子类怎么访问父类的成员变量和方法呢?
1.4.1 子类怎么访问父类的成员变量
子类访问父类的成员变量也分为两种情况,分别为不同名的成员变量如何访问、同名的成员变量如何访问。
1.4.1.1 子类和父类的成员变量不同名
public class Test1 {public int a = 1;public int b = 2;
}public class Test2 extends Test1{public int c = 3;public void test(){System.out.println(a);//从父类中继承下来的aSystem.out.println(b);//从父类中继承下来的bSystem.out.println(c);//自己类的c}
}public class Main {public static void main(String[] args) {Test2 test2 = new Test2();test2.test();}
}//运行结果
1
2
3
1.4.1.2 子类和父类的成员变量同名
public class Test1 {public int a = 1;public int b = 2;
}public class Test2 extends Test1{public int b = 5;public int c = 3;public void test(){System.out.println(a);//从父类继承下来的aSystem.out.println(b);//是访问父类继承下来的b还是自己类的b呢System.out.println(c);//自己类的c}
}public class Main {public static void main(String[] args) {Test2 test2 = new Test2();test2.test();}
}//执行结果
1
5
3
根据执行结果来看,访问的是自己类的b
如果我们将Test2的代码改动,如下
public class Test2 extends Test1{public int b = 5;public int c = 3;public void test(){System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(d);}
}
访问父类和子类都没有的成员变量编译器会报错。
结论:
- 如果访问的成员变量子类中有时,就访问子类自己的成员变量。
- 如果访问的成员变量子类中没有时,就访问父类中的成员变量,如果父类中也不存在该成员变量,编译器报错。
- 如果访问的成员变量子类中和父类中同名时,优先访问子类的
即优先访问子类自己的,如果没有再去访问父类的。
1.4.2 子类怎么访问父类的成员方法
同上,分为不同名的成员方法如何访问、同名的成员方法如何访问。
1.4.2.1 子类和父类的成员方法不同名
public class Test1 {public void f1(){System.out.println("Test1的方法f1");}
}public class Test2 extends Test1{public void f2(){System.out.println("Test2方法中的f2");}public void test(){f1();//访问父类中的该方法f2();//访问子类中该方法}
}public class Main {public static void main(String[] args) {Test2 test2 = new Test2();test2.test();}
}//运行结果
Test1的方法f1
Test2方法中的f2
1.4.2.2 子类和父类的成员方法同名
public class Test1 {public void f1(){System.out.println("Test1的方法f1");}public void f2(){System.out.println("Test1的f1方法");}
}public class Test2 extends Test1{public void f1(int a){System.out.println("Test2的方法f1");}public void f2(){System.out.println("Test2的方法f2");}public void test(){f1();//没有传参,访问父类中的该方法f1(1);//传参,访问自己类中的该方法f2();//访问子类中的该方法}
}public class Main {public static void main(String[] args) {Test2 test2 = new Test2();test2.test();}
}//执行结果
Test1的方法f1
Test2的方法f1
Test2的方法f2
结论:
- 如果访问的成员方法不同名时,优先在子类中找,找到则访问,找不到在父类中找;如果父类和子类都没有时,则编译器报错。
- 如果访问的成员方法同名时,优先访问自己的;如果父类和子类同名方法的参数列表不同(重载),根据调用
方法适传递的参数选择合适的方法访问。
有点给我写懵了,明天再写吧,嘻嘻
未完待续~
不要走开,明天再来