Java中继承关系的理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中继承关系的理解相关的知识,希望对你有一定的参考价值。

因为Java基础很薄弱,想问一个关于继承的例子。
class P

private int val = 10;
public void output()

System.out.println("P.output(),val+"+val);

public P()

System.out.println("P constructor");
output();



public class A extends P

private int val = 1;
public void output()

System.out.println("A.output(),val="+val);

public A(int val)

this.val = val;
System.out.println("A constructor");

public static void main(String[] args)

A a = new A(5);



为什么运行结果如下:

P constructor
A.output(),val=0
A constructor
为什么A.output(),val=0中val的值不是1或5,而是0呢?我不明这个地方是怎么回事。

继承关系
1、超类和子类的基本概念
2、子类不能继承父类的构造方法。
关于构造方法
执行子类的构造方法的时候,第一步该构造方法要先调用一遍父类的无参数的构造方法。
但是如果子类里面没有任何构造方法,则调用父类的无参构造方法。
可以看相关演示程序1。

演示程序2 是一个App.java不能编译的程序。根据编译时候报的错误,我们可以证明构造方法不能继承。

演示程序3 说明如果子类里面没有任何构造方法,则调用父类的无参构造方法。
覆盖
如果子类中定义的方法跟超类相同,那么,子类的方法将覆盖父类的方法。
覆盖的原则
1、方法名和参数的次序应该同超类方法中的完全相同;
2、两个方法的返回类型必须相同;
3、覆盖方法不能比被其覆盖的超类中的方法访问性差。
例如超类中被覆盖方法被说明成public,你不能在子类中用private关键字覆盖它。
4、覆盖方法不能比被覆盖方法引起更多的异常。
几种约束:
1、子类方法的名称、参数签名和返回类型必须与父类方法的名称、参数签名和返回类型一致。
如 这段代码是错误的。
public class Base

public void method()
...


public class Sub extends Base

public int method()
...

下面的则是正确的
public class Base

public void method()
...


public class Sub extends Base

public void method()...
public int method()(int a)
...

2、子类方法不能缩小父类方法的访问权限。
如下面代码就是错误的
public class Base

public void method()
...

public class extends Base

private void method()
...

3、子类方法不能抛出比父类方法更多的异常。
子类方法必须抛出的异常跟父类方法的异常相同,或者子类方法抛出的异常类是父类方法抛出的异常类的子类。
以下代码假设 ExceptionSub1 ExceptionSub2 是ExceptionBase类的子类。这段代码是正确的。

public class Base

void method() throws ExceptionBase()

public class Sub1 extends Base

void method() throws ExceptionSub1()

public class Sub2 extends Base

void method() throws ExceptionSub1,ExceptionSub2()

public class Sub3 extends Base

void method() throws ExceptionBase()

以下代码则是错误的
public class Base

void method() throws ExceptionSub1

public class Sub1 extends Base

void method() throws ExceptionBase();

public class Sub2 extends Base

void method() ExceptionSub1,ExceptionSub2;

4、方法的覆盖是指的继承的父类和子类之间。同一个类中方法只能被重载,不能被覆盖。
5、父类的静态方法不能被子类覆盖为非静态的方法。
以下代码错误
public class Base

public static void method()


public class Sub extends Base

public void method()

6、子类可以定义与父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法。
在编译时,子类定义的静态方法也必须满足:方法的参数签名一致,返回类型一致,不能缩小
父类方法的访问权限,不能抛出更多的异常。
7、父类的非静态方法不能被子类覆盖为静态方法。
以下代码错误
public class Base

void method()...


public class Sub extends Base

static void method()

8、父类的私有方法不能被子类覆盖。
9、父类的抽象方法可以被子类通过两种途经覆盖:一是子类实现父类的抽象方法;二是子类重新声明父类的抽象方法。
以下代码合法:
public abstract class Base

abstract void method1();
abstract void method2();


public abstract class Sub extends Base

public void method1()...
public abstract void method2();

10、父类的非抽象方法可以被覆盖为抽象方法。
public class Base

void method()


public abstract class Sub extends Base

public abstract void method();
参考技术A 很简单 流程问题
创造子类对象时候 先调用父类无参构造方法
所以先运行
public P()

System.out.println("P constructor");
output();

然后调用output();
public void output()

System.out.println("P.output(),val+"+val);

这里是重点 因为子类存在private int val = 1; 覆盖了private int val = 10; 但是这个时候并没有读到private int val = 1所以是默认值0
最后调用
public A(int val)

this.val = val;
System.out.println("A constructor");

所以就是
P constructor
A.output(),val=0
A constructor本回答被提问者采纳

java中继承的关系

当有父子关系的两个类(继承关系),当子类实例化对象的时候  会默认调用父类的无参构造方法,如果有  super()的话,调用的是父类有参的构造方法!

也就是说 父类必须有 有参构造 没有的话super()关键字会报错!

 

 这个的打印结果是

父类的构造方法中的输出语句
子类的show方法

以上是关于Java中继承关系的理解的主要内容,如果未能解决你的问题,请参考以下文章

java中继承的关系

java中继承的好处是啥,在组合和继承中该如何取舍?

java中继承和多态

C#中继承问题

JAVA中继承时方法的重载(overload)与重写/覆写(override)

JavaScript中继承的实现