Java入门-三大特征:继承

继承的快速入门:

认识继承(extend):

Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。

public class B extends A{

}

这里的B继承(extends)了A,被称为A的子类(派生类)。A被称为父类(基类)

继承的特点:子类能继承父类的非私有成员(成员变量、成员方法)。

继承后对象的创建:子类对象的创建是由子类、父类共同完成的。

继承的应用场景:

使用继承可以减少重复代码的编写。

如图,teacher类和consultant类存在大量重复代码,如何减少代码量?

解决思路:将重复的内容封装成一个people类,然后使teacher类和consultant类继承people类。

尽管teacher类和consultant类的代码看似不完整,但子类对象的创建是由子类、父类共同完成的。所以对对象并没有影响。

继承相关的注意事项:

1.权限修饰符

什么是权限修饰符?

就是是用来限制类中的成员(成员变量、成员方法、构造器、代码块…)能够被访问的范围。

权限修饰符有几种?各自的作用是什么?

缺省,即没有修饰符,又被称为default或friendly

2.单继承,Object

单继承:Java是单继承的,Java中的类不支持多继承,但是支持多层继承。

人话:每次只能继承一个类,但是可以重复继承:c继承b,b继承a。

Object类:java所有类的祖宗类。我们写的任何一个类,其实都是object的子类或子孙类

换句话说,创建的所有类都可以直接继承并调用Object的变量与方法。

3.方法重写:

什么是方法重写?

  • 当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写。
  • 注意:重写后,方法的访问,Java会遵循就近原则。

方法重写的其它注意事项

  • 使用@Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
  • 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )。
  • 重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
  • 私有方法、静态方法不能被重写,如果重写会报错的。

方法重写的实际应用:

重写toString方法:

子类重写Object类的toString()方法,以便返回对象的内容。

    public String toString(){
        return value;
    }

4.子类中访问其他成员的特点:

在子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的。

public class A {
    String name="A变量";
}
class B extends A{
    String name="B变量";
    public void ShowName(){
        String name="局部变量";
        System.out.println(name);
    }
}
//此时ShowName打印的是"局部变量"

要想访问B的name怎么办?

System.out.println(this.name);
//此时ShowName打印的是"B变量"

要想访问A的name怎么办?

使用“super”关键字

System.out.println(super.name);
//此时ShowName打印的是"A变量"

成员方法和成员变量同理,执行就近原则。

5.子类构造器的特点:

子类的全部构造器,都会先调用父类的构造器,再执行自己。

子类构造器是如何实现调用父类构造器的:

  • 默认情况下,子类全部构造器的第一行代码都是 super() (写不写都有) ,它会调用父类的无参数构造器。
  • 如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器。
public class A {
    A(){
        System.out.println("==A的无参构造器被调用了==");
    }
}
class B extends A{
    B(){
        System.out.println("==B的无参构造器被调用了==");
    }

}

此时new一个B类的对象,会先打印“==A的无参构造器被调用了==”,再打印“==B的无参构造器被调用了==”。

同样,即使子类是有参数构造器,也会先调用父类的无参数构造器。

原因:子类的构造器中,第一行默认存在super()关键字,即自动调用父类无参构造器。

假设父类只有有参构造器而没有无参构造器呢?

此时必须手写出super(),指定调用父类的有参构造器。

比如:

public class A {
    A(String name,int age){
        System.out.println("==A的无参构造器被调用了==");
    }
}
class B extends A{
    B(){
        super("kevin",19);
        System.out.println("==B的无参构造器被调用了==");
    }
}

//如果你希望子类创建有参数构造器,使创建对象的时候可以直接传参

class B extends A{
    B(String name,int age){
        super(name,age);
        System.out.println("==B的无参构造器被调用了==");
    }
}

为什么子类构造器里要调用父类构造器?

由于引入了继承的概念,导致创建对象的时候分为父类和子类。可能有些成员变量是父类的,有些成员变量是子类的。如果我们想写一个子类有参构造器,为对象直接传参时,我们不能直接指定那些父类的变量传参(this.xxx=xxx)(因为这些变量实质上不是子类的),所以引入super关键字,如上方代码。

补充:this()调用兄弟构造器:

任意类的构造器中,是可以通过this(…) 去调用该类的其他构造器的。

此时构成了构造器重载关系。

注意:this(…)super(…) 都只能放在构造器的第一行,因此,有了this(…)就不能写super(…)了,反之亦然。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值