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

本文深入解析Java中的继承概念,包括继承的类型、方法与属性的继承规则、内部类的继承、方法重载与重写的区别及调用顺序,以及继承过程中需要注意的事项。


类要么是用来继承的,要么是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关键字来指明初始化父类的哪个构造函数。
  • 一个类可以有很多代,一定注意强转。
  • 只有非静态方法有重写一说,静态方法,属性不存在重写。即向上转型的对象不能调用子类扩展的方法跟属性。

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

每篇一语

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

<think>嗯,用户问的是Java中的继承,我得先回顾一下继承的基本概念。继承是面向对象编程的四大特性之一,另外三个是封装、多态和抽象。继承的作用主要是实现代码复用,允许子继承的属性和方法,并且可以扩展或修改这些方法。 首先,要解释什么是继承。在Java中,继承通过extends关键字实现。比如,子继承后,可以重用父的字段和方法。同时,子可以添加自己的新方法,或者重写父的方法来改变行为。例如,Animal作为父,Dog作为子,Dog可以继承Animal的eat()方法,也可以覆盖它,或者新增bark()方法。 然后需要考虑用户可能想知道继承的优点。代码复用肯定是重点,避免重复代码,提高开发效率。另外,继承也支持多态,这是另一个核心概念。不过要注意Java是单继承,一个只能有一个直接父,这点需要提到,避免用户误解。 接下来,可能需要给出一个代码示例。比如父Animal有name属性和eat()方法,子Dog继承它,并添加bark()方法。同时,可以展示方法重写,比如Dog的eat()方法覆盖父的实现。这样用户能直观看到继承的结构和用法。 然后,解释继承中的关键点,比如构造方法的调用顺序。子构造方法会默认调用父的无参构造,如果父没有无参构造,子必须显式调用super()。这点容易出错,需要特别说明。另外,访问修饰符的影响,比如private成员不能被继承,protected和public可以。 可能用户还会混淆继承与接口的实现,所以应该提到接口可以实现多重继承的效果,而只能单继承。这也是Java设计上的一个特点,避免多继承的复杂性,比如菱形问题。 最后,相关问题需要围绕继承的各个方面展开。比如继承的优缺点,方法重写与重载的区别,super关键字的作用,单继承的限制等等。这些问题能帮助用户进一步深入理解继承相关的知识。</think><< **继承**是面向对象编程中的核心概念,允许一个(子/派生)基于另一个(父/基)构建,继承其属性和方法,同时可以扩展或修改功能。以下是继承的关键点: ### 实现方式与特点: 1. **代码复用**:子可以直接使用父的非私有(`public`/`protected`)字段和方法,无需重复编写。 2. **扩展性**:子可以添加新方法或重写(Override)父方法以改变行为。 3. **单继承限制**:Java仅支持单继承(一个子只能继承一个父),但可通过接口实现多继承效果。 4. **`super`关键字**:用于访问父的成员(方法、构造方法、字段)。 ### 代码示例: ```java // 父 class Animal { protected String name; public Animal(String name) { this.name = name; } public void eat() { System.out.println(name + " is eating."); } } // 子继承 class Dog extends Animal { public Dog(String name) { super(name); // 调用父构造方法 } // 扩展新方法 public void bark() { System.out.println(name + " is barking."); } // 重写父方法 @Override public void eat() { System.out.println(name + " eats bones."); } } public class Main { public static void main(String[] args) { Dog dog = new Dog("Buddy"); dog.eat(); // 输出:Buddy eats bones. dog.bark(); // 输出:Buddy is barking. } } ``` ### 注意事项: - **构造方法**:子构造方法必须调用父构造方法(默认调用无参构造,否则需显式用`super(...)`)。 - **访问权限**:父的私有(`private`)成员无法被直接继承。 - **方法重写**:子重写父方法时,需遵循方法签名(名称、参数、返回型)完全一致,且访问权限不能更严格。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值