面向对象---继承之方法覆盖及 final 关键字

方法覆盖(重写):

​ 子类中可以定义和父类一模一样的方法

​ 在子类中访问这个一模一样的方法,访问到的是子类中定义的方法

​ 在父类中访问这个一模一样的方法,访问到的还是子类定义中的方法

子类中的方法在调用的时候(对象才能调用):

​ 1、在子类自己定义的方法中查找调用的目标方法,如果找到就执行

​ 2、如果在子类自己定义的方法中没找到目标方法,才会在父类定义的方法中 查找调用的目标方法。

​ 对于父类中的方法调用而言,查找目标方法的过程和子类中方法的查找过程一模一样

​ 1、先在子类中查找,如果找到就执行

​ 2、如果子类中找不到,此时再去父类中查找。

上诉两种情况针对的都是子类对象调用方法的时候,如果调用的是子类方法,则是第一种情况,如是调用的父类方法,则是第二种情况,但两种情况都是先去子类中查找

    public class Demo1 {

      public static void main(String[] args) {
        //OverrideSon1 son = new OverrideSon1();
        // 测试在子类类体中,访问子类和父类定义的一模一样的方法
        //son.callSameMethod(); //son
        // 测试在父类类体中,访问子类和父类定义的一模一样的方法
        //son.call(); // son
        //测试在子类中能否既访问到子类中定义的一模一样的方法,也访问到父类中定义的一模一样的方法
        //son.callAll();

        //
        //OverrideSon2 son2 = new OverrideSon2();
        //son2.callSameMethod();
        //son2.call();
        //son2.callAll();

        //只有在 子类对象上调用方法 的时候,才会出现
        //1. 在子类对象对应的子类类型中找目标方法
        //2. 如果没找到,在到父类中找

        //如果对于非子类对象
        //OverrideFather overrideFather = new OverrideFather();
        //overrideFather.sameMethod();

        //我能不能在父类中,访问到子类中的成员变量的值呢?
        OverrideSon1 overrideSon1 = new OverrideSon1();
        overrideSon1.test();
      }
    }
    class OverrideFather {

      private int i = 100;

      //父类中和子类定义的一模一样的方法
      public void sameMethod() {
        System.out.println("father");
      }

      public void call() {
        sameMethod();
      }

      /*
          通过方法覆盖,可以让父类,访问到子类中定义的同名成员变量的值
       */
      public void test() {
        // 1. getI() 返回成员变量i的值
        // 2. 子类中的getI()方法返回的是子类对象的i值,父类中的getI方法返回的是父类中的i值
        // 3. 方法覆盖就产生了,在父类中调用的getI(), 实际调用到的是子类中定义的get()
        System.out.println(getI());
      }

      public int getI() {
        return i;
      }
    }
    class OverrideSon1 extends  OverrideFather {

      int i = 1000;
      //父类中和子类定义的一模一样的方法
      public void sameMethod() {
        System.out.println("son");
      }

    public void callSameMethod() {
        //在子类中,通过方法名,调用子类和父类中定义的一模一样的方法
        sameMethod();
      }

      public void callAll() {
        sameMethod(); //直接访问到的是子类中自己定义的一模一样的方法

        //调用父类中定义的一模一样的方法
        super.sameMethod();
      }

      public int getI() {
        return i;
      }
    }

    class OverrideSon2 extends  OverrideFather {

      //父类中和子类定义的一模一样的方法
      public void sameMethod() {
        System.out.println("son 2");
      }

    public void callSameMethod() {
        //在子类中,通过方法名,调用子类和父类中定义的一模一样的方法
        sameMethod();
      }

      public void callAll() {
        sameMethod(); //直接访问到的是子类中自己定义的一模一样的方法

        //调用父类中定义的一模一样的方法
        super.sameMethod();
      }
    }

子类方法覆盖父类方法的条件:

​ 1、方法的权限满足的条件:子类方法的访问权限不能小于父类的访问权限

​ 2、方法的返回值类型:a、子类方法返回值类型和父类返回值类型相同

​ b、当父类方法的返回值类型,是引用类型的时候,如 果子类方法的返回值类型是父类返回值类型的子类 类型

​ 3、方法签名必须一致。

      public class Demo2 {

      public static void main(String[] args) {
        MySon mySon = new MySon();
        //mySon.test();

        MyFather myFather = new MyFather();
        //myFather.test();
       mySon.test();
      }

    }

    class MyFather {

      public void test() {
        //method(10, null);
        privateMethod();
      }

      A method(int a, A aa) {
        System.out.println("MyFather");
        return null;
      }

    private void privateMethod() {
        System.out.println("father privateMethod");
      }

      public static void staticMethod() {
        System.out.println("MyFather staticMethod");
      }

    }

    class MySon extends MyFather {
                          //如果说我们在方法上放了override注解,其实告诉编译器,
      @Override          // 该方法要覆盖父类中的方法,
      B method(int b, A bb) {
        System.out.println("MySon");
        return null;
      }

    //@Override
      public void privateMethod() {
        System.out.println("son privateMethod");
      }

      // @Override
      public static void staticMethod() {
        System.out.println("MySon staticMethod");
      }
    }
    class A {

    }
    class B extends A {

    }

方法覆盖的意义:在子类中,修改父类的方法实现,所谓修改父类被覆盖方法的实现,并没有物理修改父类的方法实现,只是让实际调用的时候调用了子类中的方法,看起来就像父类的方法被修改了。

​ 注意事项:1、private修饰的方法不能被覆盖。

​ 2、静态方法不能被覆盖

final关键字:final是最终的意思,可以修饰类、变量、成员方法

​ 修饰类,类不能被继承

​ 修饰变量,变量就变成了常量,只能被赋值一次

常量包括字面值常量和自定义常量,这里被 final 修饰的变量就是自定义常量。

​ 修饰方法,方法就不能被覆盖。

***其中修饰变量分两种情况:***1、修饰局部变量的时候,必须保证局部变量在使用之前被赋一次值

​ 2、修饰成员变量的时候,必须保证在对象创建完成之前,我们必须通 过代码给final修饰的成员变量赋值一次,这里所谓的赋值一次不 包括 jvm 赋予默认初值的那一次。

    public class Demo1 {

      public static void main(String[] args) {
        A a = new A();
        //A a1 = new A(10);

        //有一个小点
        final A finalLocal = new A();
        // 被一个final修饰的引用变量,它指向的对象本身数据是可变的
        finalLocal.setIntValue(88);
        System.out.println(finalLocal.getIntValue());

        //被final修饰的引用变量,不可变的仅仅只是这个引用变量本身的值
        //finalLocal = a;
      }

    }

    // 被final修饰的类无法被继承
    //final
    class A {

      final int finalValue1 = 1;
      final int finalValue2;
      final int finalValue3;
      private int intValue;
	{
        finalValue3 = 200;
      }

      public A () {
        finalValue2 = 100;
      }

      /*
          如果要用构造方法给final修饰的成员变量赋值
          必须保证,每个构造方法中,必须给这个final修饰的成员变量赋值赋予初值
       */
      public A (int i) {
        //
        finalValue2 = 90;
      }
	public final void testFinal() {

        final int a = 10;
         // 被final修饰的局部变量,只能在使用前辈赋值一次
        // a = 100;
        System.out.println(a);

      }

      public int getIntValue() {
        return intValue;
      }

      public void setIntValue(int intValue) {
        this.intValue = intValue;
      }

    }
    class B extends A {

      // 被final修饰的方法不能被覆盖
      //public void testFinal() {
      //
      //}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值