java继承之属性与方法访问

  • 以下讨论都是基于从子类实例进行属性/方法访问出现的情况.建议先看文章-jvm解析与分派

1.从父类方法(未重写)访问属性时,永远都只使用父类属性.

public class Test {
    public static void main(String[] args) throws Exception{
        F f = new S();
        f.prt();// --> 返回f.
    }
}
class F{
    public String share = "f";
    public void prt(){
        System.out.println(share);
    }
}
class S extends F{
    public String share = "s";
}

2.从父类方法(未重写)访问方法f时,若f在子类中重写,则使用子类的重写方法.
//这也是为什么在父类构造器中,不提倡调用可重写方法的原因,因为创建一个子对象时,需要先实例化一个父对象,此时若是调用了子类中的重写方法,则很有可能因为子对象未初始化而造成一些错误(如NullpointException).

public class Test {
    public static void main(String[] args) throws Exception{
        F f = new S();
        f.prt();// --> 返回son.
    }
}
class F{
    public String share = "f";
    public void prt(){
        //实际调用了子类的重载方法
        f();
    }
    public void f(){
        System.out.println("father");
    }
}
class S extends F{
    public String share = "s";
    @Override
    public void f(){
        System.out.println("son");
    }
}
  • 从子类访问父类属性x(可继承)时,若该属性的同名属性在子类中有定义,则直接修改的是子类中的属性,不影响父类属性.如果子类中没有同名属性,则使用父类属性进行操作.

(1) 子重定义父类同名属性,则不影响父类属性

public class Test {
    public static void main(String[] args) throws Exception{
        F f = new S();
        f.prt();// --> 返回son.
    }
}
class F{
    public String share = "f";
    public void prt(){
        //实际调用了子类的重载方法
        showData();//打印 sss|f
    }
    void showData(){}
}
class S extends F{
    public String share = "s";
    @Override
    public void showData(){
        //修改子类重复定义的属性无影响
        share = "sss";
        System.out.println(this.share+"|"+super.share);
    }
}

(2) 子类直接使用父类的继承属性

public class Test {
    public static void main(String[] args) throws Exception{
        F f = new S();
        f.prt();// --> 返回son.
    }
}
class F{
    public String share = "f";
    public void prt(){
        //实际调用了子类的重载方法
        showData();
    }
    void showData(){}
}
class S extends F{
    @Override
    public void showData(){
        //修改子类重复定义的属性无影响
        share = "sss";
        System.out.println(share == super.share);//打印true
        System.out.println(this.share+"|"+super.share);//打印 sss|sss
    }
}
  • 在父类的可访问方法中调用一个可重写方法,要谨慎,很容易使子类实现者出现错误.
    错误示例,以下代码会引发一个StackOverFlow
public class Test {
    public static void main(String[] args) throws Exception{
       F fout = new S();
        fout.invoke();
    }
}
class F{
    public void invoke(){
        fx();
    }
    public void fx(){}
}
//在不知道父类的方法调用的情况下容易写出以下代码.
//陷入无限递归中
class S extends F{
    public void fx(){
        this.invoke();
    }
}

你可能感兴趣的:(java,继承,实例)