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);//从父类中继承下来的a
System.out.println(b);//从父类中继承下来的b
System.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);//从父类继承下来的a
System.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
结论:
- 如果访问的成员方法不同名时,优先在子类中找,找到则访问,找不到在父类中找;如果父类和子类都没有时,则编译器报错。
- 如果访问的成员方法同名时,优先访问自己的;如果父类和子类同名方法的参数列表不同(重载),根据调用
方法适传递的参数选择合适的方法访问。
有点给我写懵了,明天再写吧,嘻嘻
未完待续~
不要走开,明天再来