Java继承问题

Java继承问题

  在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写(Override)。方法重写又称方法覆盖。
  重写只针对方法,子类和父类中的同名属性只是子类覆盖了父类的相同属性
  父类中的所有属性和方法都会被子类继承(private修饰的属性方法只是拥有,只能使用子类中的方法调用),子类在继承的时候,子类外部可以调用从父类中继承下来的属性和方法(私有的除外),另外 final方法、私有方法、static方法是不能重写的,但私有方法和static方法可以使用同名同参方法重新定义,但没有多态的特性。

/**
 * 测试Java的继承
 * @author liuhongjun
 * @create 2020-11-23 20:34
 */
public class ExtendsTest {
    public static void main(String[] args) {

        Z z = new Z();
        System.out.println("===========子类对象调用属性=============");
        System.out.println(z.defaultField); //子类未定义该属性,调用的是从父类中继承的缺省属性
        System.out.println(z.finalField);
        System.out.println(z.protectedField);
        System.out.println(z.staticField);
        System.out.println(z.extendField);

        System.out.println("===========子类对象调用方法=============");
        z.defaultMethod();
        z.protectedMethod();

        z.finalMethod(); //final类型不能被重写、重定义,调用的是从父类继承的final方法
        z.extendMethod();
        z.staticMethod(); //调用的是子类重定义的static方法


        System.out.println("=============调用属性===========");


        F f = new Z(); //多态性
        //调用的都是父类的属性
        System.out.println(f.defaultField);
        System.out.println(f.protectedField);
        System.out.println(f.finalField);
        System.out.println(f.staticField);

        System.out.println("============调用方法============");
        // 被重写的方法在编译期看左边进行调用,运行期看右边
        f.protectedMethod(); //调用子类重写方法
        f.staticMethod(); //子类不会重写静态方法,调用的是父类的方法,子类也有同名方法,但是不属于重写,无法调用
        f.defaultMethod(); //调用子类重写方法
        f.finalMethod();  //子类不会重写final方法,调用的是父类的final方法
        f.method(); //调用子类重写的方法,这个是返回值类型不同

        System.out.println("============强转之后调用子类属性方法============");
        //需要转型,才能使用子类特有方法属性
        Z zz = ((Z) f);
        System.out.println(zz.extendField); //调用子类特有的属性
        System.out.println(zz.protectedField); //调用子类重新定义的属性
        System.out.println(zz.defaultField); //调用从父类中继承的属性

        zz.extendMethod(); //调用子类特有的方法
        zz.staticMethod(); //调用的是子类重定义的static方法
        zz.finalMethod();  //子类不会重写final方法,调用的是父类的final方法
        zz.defaultMethod(); //调用子类重写的方法
    }
}


class F {

    public final String finalField = "父类final属性";

    public static String staticField = "父类static属性";

    String defaultField = "父类缺省属性";

    protected String protectedField = "父类protected属性";

    private String privateField = "父类私有属性";


    public static void staticMethod(){
        System.out.println(">>>>>>>>>>>>>>>>>>>父类static方法");
    }

    //不能被重写
    public final void finalMethod(){
        System.out.println(">>>>>>>>>>>>>>父类final方法");
    }

    void defaultMethod(){
        System.out.println(">>>>>>>>>>>>>>>父类缺省方法");
    }

    protected void protectedMethod(){
        privateMethod();
        System.out.println(">>>>>>>>>>>>>>>父类protected方法");
    }

    private void privateMethod(){
        System.out.println(privateField);
        System.out.println(">>>>>>>>>>>>>>>父类private方法");
    }

    public F method(){
        System.out.println("父类返回值类型不同的重写");
        return new F();
    }
}

class Z extends F {
    //把从父类中继承的同名属性重定义,属性没有重写的概念
    public final String finalField = "子类final属性";
    public static String staticField = "子类static属性";
    //String defaultField = "子类缺省属性";
    protected String protectedField = "子类protected属性";
    private String privateField = "子类私有属性";
    public String extendField = "子类扩展的属性";

    public static void staticMethod(){
        //静态方法中不能使用this、super关键字,这两个关键字属于对象
        //this.privateMethod();
        //super.defaultMethod();
        System.out.println(">>>>>>>>>>>>>>>>子类static方法(重定义)");
    }

    //子类方法的返回值必须【小于等于】父类方法的返回值范围(父类返回值或其子类,父类为void 基本数据类型,子类就需要一致)
    //子类方法的权限必须【大于等于】父类方法的权限修饰符
    //子类方法的异常必须【小于等于】父类方法的异常
    void defaultMethod(){
        System.out.println(">>>>>>>>>>>>>>>>>>子类缺省方法(重写)");
    }

    protected  void protectedMethod(){
        System.out.println(">>>>>>>>>>>>>>>子类protected方法(重写)");
    }

    private void privateMethod(){
        System.out.println(">>>>>>>>>>>>>>>>>>>子类private方法(重定义)");
    }

    //继承之后不能重写
//    public final void finalMethod(){
//        System.out.println(">>>>>>>>>>>>>子类final方法");
//    }

    public final void finalMethod(String param){
        System.out.println(">>>>>>>>>>>>>子类final方法,同名不同参");
    }

    public Z method(){
        System.out.println("子类返回值类型不同的重写");
        return new Z();
    }

    public void extendMethod(){
        System.out.println("子类中的扩展方法");
        //子类通过super调用父类方法或属性
        System.out.println("****************子类通过super调用父类方法或属性*******************");
        super.staticMethod();
        super.defaultMethod();
        super.finalMethod();
        super.protectedMethod();
        System.out.println("********************************************************");
        //调用从父类中继承下来的final方法
        System.out.print("子类方法内部,调用从父类中继承下来的final方法:");
        this.finalMethod();
        this.finalMethod("123213");
        System.out.print("子类方法内部,子类把继承过来的private方法进行了重定义:");
        this.privateMethod();
    }


}

  在Java中,如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。

正如同《Java编程思想》中所说:“一旦你了解了多态机制,可能就会认为所有事物都可以多态地发生。然而,只有普通方法的调用可以是多态的。”这也很好地理解了,为什么在Java中,static方法和final方法(private方法属于final方法)是前期绑定,而其他所有的方法都是后期绑定了。

补充:
1、权限修饰符:重写的方法的权限必须大于等于被重写的方法的权限
2、抛异常:重写的方法抛出的异常必须小于等于被重写的方法的异常
3、返回值:
  1)被重写的方法为void、基本数据类型 ,则重写的方法为void、基本数据类型
  2)重写的方法的返回值类型可以为被重写方法的子类(不能为父类)

代码块:由父及子,静态先行

public class Test {

    public void test(){
        Son son = new Son();
    }

    /*
        父类静态代码块
        子类静态代码块
        父类非静态代码块
        父类构造器
        子类非静态代码块
        子类构造器
     */

}


class Parent {
    public Parent(){
        System.out.println("父类构造器");
    }

    {
        System.out.println("父类非静态代码块");
    }

    static{
        System.out.println("父类静态代码块");
    }
}

class Son extends Parent {
    public Son(){
        System.out.println("子类构造器");
    }

    {
        System.out.println("子类非静态代码块");
    }


    static{
        System.out.println("子类静态代码块");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值