Java继承(Inheritance)

  这个继承可真的是太南了!

继承(Inheritance)

  子类拥有父类非 private的属性、方法。
  Java不支持多继承,但支持多重继承。
types_of_inheritance-1.png

抽象类

  抽象类不能直接New一个对象,需要用extends来定义在父类中的abstract内容。直到所有的abstract变量和函数全都被重写,才可以New对象。

Creature cCreature = new Turtle();问题

  在New对象的时候,也会先走父类函数,如果子类对父类有重写,则运行子类重写的函数。如果子类对父类有重载,则按照相应规则进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Father{
public void func1(){
func2();
}
//这是父类中的func2()方法,因为下面的子类中重写了该方法所以在父类类型的引用中调用时,这个方法将不再有效
//取而代之的是将调用子类中重写的func2()方法
public void func2(){
System.out.println("AAA");
}
}


public class Child extends Father{
//func1(int i)是对func1()方法的一个重载由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用
//所以在下面的main方法中child.func1(68)是不对的
public void func1(int i){
System.out.println("BBB");
}
//func2()重写了父类Father中的func2()方法如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法
public void func2(){
System.out.println("CCC");
}
}



public class PolymorphismTest {
public static void main(String[] args) {
Father child = new Child();
child.func1();//打印结果将会是什么?
}
}

  上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。
  那么该程序将会打印出什么样的结果呢?很显然,应该是“CCC”。

  这就可以很好解释我在QMPlus上问的问题了。代码位置:Code\Set_12\slides_41

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.*;

public class DoctorTest {

public static void main(String[] args) {
ArrayList<Doctor> dlist = new ArrayList<Doctor>();
dlist.add(new Doctor());
dlist.add(new Surgeon());
dlist.add(new FamilyDoctor());
dlist.add(new Surgeon());

for (Doctor d : dlist) {
d.treatPatient();
// d.giveAdvice();
}

//System.out.println(dlist.get(2).giveAdvice());
// System.out.println(dlist.indexOf(new FamilyDoctor()));
}

// dlist.get(2).giveAdvice();
// dlist.get(1).makeIncision();

}

//如何在ArrayList中没用命名的情况下调用里面的函数
//如何在ArrayList中对象没有命名的时候 用indexOf索引出来

  为什么FamilyDoctor不能giveAdvice()?为什么Surgeon不能makeIncision()?明明在他们自己的类中都有定义?
  因为,这个里面新建的是Doctor ArrayList,所以只能进行Doctor的操作,其他单独特有的操作,在这个ArrayList里面是无法进行的。
  同时,ArrayList可以直接用indexOf(int n),n为对象所在的位置。
  同时下面这个问题和上面的问题一样,父类无法调用子类,如果没有复写的话。 位置:Code\Set_12\slides_32

1
2
3
4
5
6
7
8
import java.awt.*;

public class Turtle extends Creature{
public void success(){
System.out.println("Create a Turtle object successfully");
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MakeCreatures {
public static void main(String[] args) {
MakeCreatures mCreat = new MakeCreatures();
mCreat.go();
}

public void go() {
// Creature aCreature = new Creature();

Creature bCreature = new Rabbit();
bCreature.run(5, true);

Creature cCreature = new Turtle();
System.out.println(cCreature);
// cCreature.success(); 因为cCreature创造的是父类,无法调用子类的函数
cCreature.swim(5);
}
}

  cCreature.success(); 因为cCreature创造的是父类,无法调用子类的函数。

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。就是说子类能够根据需要实现父类的方法。
1.参数列表必须完全与被重写方法的相同。
也就是比如 public void sell(){ }
重写的子类中也必须是 public void sell() {}
如果是 public int sell() {} 会报错 “ 返回类型int与void不兼容 ”
2.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
3.构造方法不能被重写。
4.如果不能继承一个方法,则不能重写这个方法。
5.重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
1.被重载的方法必须改变参数列表(参数个数或类型不一样);
2.被重载的方法可以改变返回类型;
3.被重载的方法可以改变访问修饰符;
4.被重载的方法可以声明新的或更广的检查异常;
5.方法能够在同一个类中或者在一个子类中被重载。
6.无法以返回值类型作为重载函数的区分标准。

重写与重载之间的区别

区别点 重载方法 重写方法
参数列表 必须修改 一定不能修改
返回类型 可以修改 一定不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)


参考文献

【java基础】——java中父类声明子类实例化


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!