到底什么是继承?继承的注意事项


类要么是用来继承的,要么是final的。此处的类指自己写的类、jar包中的类。比如可以实现ThreadPoolExecutor类,在任务执行前执行后加入自己的逻辑。spring jar中的类等等都可继承。只要不是final的都可继承。

什么是继承

java类默认继承Object类,因此所有的类对象类型都是Object类型。
使用extends关键字便是继承。继承的是什么?

继承了父类的类型

比如 B implements C,D; A extends B implements E。

那么A类型的对象是A类型、B类型、C类型、D类型、E类型。B类型的对象是B类型、C类型、D类型。没想到特别好的例子,直接用字母代替了。转换为相应的类型后只能调用相应类型的方法加上Object的方法

public class A extends B implements E {
    public static void main(String[] args) {
        A a = new A();
        //转换为相应的类型后只能调用相应类型的方法。自动向上转型。
        if (a instanceof B) {
            B b = a;
            b.bTest();
        }

        if (a instanceof C) {
            C c = a;
            c.cTest();
        }

        if (a instanceof D) {
            D d = a;
            d.dTest();
        }

        if (a instanceof E) {
            E e = a;
            e.eTest();
        }
    }

    @Override
    public void eTest() {
        System.out.println("extends E");
    }
}

class B implements C, D {
    public  int age=10;
    public  String name = "lipp3";

    public static void staticMethod() {
        System.out.println("I am B Method");
    }

    //无论是静态的还是非静态的方法,使用了final子类便不能重写。但子类可直接调用。
    public final void finalTest() {
        System.out.println("I am B Method");
    }

    public void bTest() {
        System.out.println("I am B 方法");
    }

    @Override
    public void cTest() {
        System.out.println("extends C");
    }

    @Override
    public void dTest() {
        System.out.println("extends D");
    }
}

interface C {
    void cTest();
}

interface D {
    void dTest();
}

interface E {
    void eTest();
}
继承了父类的方法、属性

方法跟属性都会继承,private的没有访问权限。final的方法不能重写,可以直接在子类中使用。static的属性、方法可以使用对象调用也可使用类名点的方式调用。比如A类使用B类的属性跟方法。在A类的main方法中加入如下代码:

    A a = new A();
    System.out.println(a.name + "类调用: " + A.name);
    a.staticMethod();
    A.staticMethod();
继承了父类的内部类(内部类不是private的就可以)

含有内部类的类

public class Outer {
    private static int shared = 100;

    public static class StaticInner {
        //静态内部类可定义static的方法及属性,但不能够引用外部类的非静态属性及方法
        public void innerMethod() {
            System.out.println("inner " + shared);
        }
    }

    public class DynamicInner {
      //  动态内部类不能定义static的方法及属性。但可以用外部类的静态方法和属性
        public void innerMethod() {
            System.out.println("dynamic " + shared);
        }
    }
}

继承外部类。不是子类必须是代码中注释的写法。

public class OuterExtend extends Outer {
    public void test() {
        //没有使用Outer.new StaticInner();
        StaticInner staticInner = new StaticInner();
        staticInner.innerMethod();
        //没有使用 new Outer.new DynamicInner()
        DynamicInner dynamicInner =new DynamicInner();
        dynamicInner.innerMethod();
    }
}

作用

  • 复用代码(只关注子类扩展的)
  • 把类进行分类,如同动物、植物这种分开。
  • 是设计模式的基础(面向接口编程)

总结
继承即是世袭,把一切都继承过来,给了子类。private的属性、方法也继承了只是没有访问权限。

方法重载与重写及方法的调用顺序

重载方法名相同,方法参数类型或个数不同,称为重载。
重写方法名相同,方法参数类型、个数必相同,称为重写。
执行时先看子类有没有此方法,有直接调用,无继续向父类找,父类没有继续向父类找直至找到Object。这里注意方法找的是最终类型。即对象用instanceof关键字的最小子类型。
比如 A继承B;B b = new A();
b instanceof Object 是true;
b instanceof B 是true;
b instanceof A 是true;即A类型为最小子类型。
熟练后最右边是什么类型,调用方法时便从哪个类开始查找。 注意的是,A中扩展的方法、属性,对象b是调用不到的,除非强转为A类型

继承的注意事项

  • 向下强转的类型必须是右侧new 的类型。比如 A继承B,B继承C。
    B b = new B();则b不能强转成A类型,即 不允许b = new A();
    B a = new A();则a可以强转成A类型即允许a = new A();
  • 关于重写时方法的访问权限,可以与父类的不同但必须是大于等于父类的权限,比如父类的方法是public的那么子类只能是public的,若父类的方法是protected,则子类的可以是public的或者是protected。
  • 执行顺序:父类的静态代码块–>子类的静态代码块–>父类的代码块–>父类的构造函数–>子类的代码块–>子类的构造函数。
    在看开源的代码时尤其重要。当子类找不到属性赋值时,可以按照上述执行顺序进行查找。
  • 若父类有无参构造函数,new 子类时,无论调用的是有参还是无参构造函数,则都会先初始化父类的无参构造函数。当然可以使用super关键字来指明初始化父类的哪个构造函数。
  • 一个类可以有很多代,一定注意强转。
  • 只有非静态方法有重写一说,静态方法,属性不存在重写。即向上转型的对象不能调用子类扩展的方法跟属性。

更多及细节参考老马说编程

每篇一语

岁月失语,惟石能言。——冯骥才

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值