Java继承与方法的重写

一、继承

1.什么是继承?

父类怎么形成的:我们定义了多个类,发现这些类中有很多重复性的代码,我们就定义了一个父类,将相同的代码抽取出来,放到父类中,其他类直接继承这个父类,就可以直接使用父类中的内容了

2.继承的基本使用

第一步:定义一个父类,在其中定义重复性的代码

第二步:定义一个子类继承父类->extends

        子类  extends  父类

第三步:创建子类对象,直接使用父类中非私有成员,但是不能使用父类中的私有成员

public class Employee {
    String name;
    int age;


    public void work(){
        System.out.println("工作");

    }

    private void eat(){
        System.out.println("员工要吃饭");
    }
}
public class Manager extends Employee {
}






public class Teacher extends Employee {
}






public class Test01 {
    public static void main(String[] args) {

        Teacher teacher=new Teacher();
        teacher.name="明哥";
        teacher.age=18;
        System.out.println(teacher.name+"..."+teacher.age);

        teacher.work();
        //teacher.eat;   子类继承父类之后不能使用私有成员,只能使用父类非私有成员

        System.out.println("================");

        Manager manager = new Manager();
        manager.name="名";
        manager.age=18;
        System.out.println(manager.name+".."+manager.age);
        manager.work();


    }
}

3.继承中成员的访问特点

3.1成员变量

(1)子类和父类中的成员变量不重名

(2)子类和父类中的成员变量重名

public class Fu {
    int numFu=100;

    int num=1000;
}
public class Zi extends Fu {
    int numZi=10;

    int num=100000;
}
public class Test01 {
    public static void main(String[] args) {
        //创建父类对象
        Fu fu = new Fu();
        System.out.println(fu.numFu);
       // System.out.println(fu.numZi);//不能调用子类特有的成员
        System.out.println(fu.num);

        System.out.println("========");
        //创建子类对象
        Zi zi=new Zi();
        System.out.println(zi.numZi);
        System.out.println(zi.numFu);//继承了父类,可以使用父类中的非私有成员

        System.out.println(zi.num);

    }
}

总结:看等号左边是谁,先调用谁中的成员

     如果等号左边是父类类型,只能调用父类中的成员变量,如果是子类类型,既能调用子类的,还能调用父类中继承过来的非私有成员

继承前提下,成员变量访问特点口诀

(同样适用于多态)看等号左边是谁,先调用谁中的成员,子类没有,找父类

3.2成员方法

(1)子类和父类中的成员方法不重名

(2)子类和父类中的成员方法重名

public class Fu {

    public void methodFu() {

        System.out.println("我是父类中的methodFu");
    }

    public void  method(){
        System.out.println("我是父类的method");
    }
}
public class Zi extends Fu{
    public void methodZi(){
        System.out.println("我是子类中的methodZi");
    }
    public void  method(){
        System.out.println("我是子类的method");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Fu fu=new Fu();
        fu.methodFu();
        fu.method();


        System.out.println("============");
        Zi zi=new Zi();
        zi.methodZi();
        zi.methodFu();//继承父类之后,能调用父类非私有成员
        zi.method();

    }
}

二、方法的重写

概述:子类中有一个和父类的方法名以及参数列表相同的方法

前提:继承

访问:看new的是谁,先调用谁中的,如果new的是子类,调用子类重写的方法,子类没有找父类

检测是否为重写方法:在该方法上写   @Override


public class Fu {
    public void methodFu(){
        System.out.println("我是父类中的methodFu方法");
    }

    public void method(){
        System.out.println("我是父类中的method方法");
    }

    public void method01(){


    }

    public Fu method03(){

        return null;
    }

}

public class Zi extends Fu {
    public void methodZi(){
        System.out.println("我是子类中的methodzZi");
    }



    @Override
    public  void method(){
        System.out.println("我是子类中的method方法");
    }

    @Override
    public void method01(){

    }



    @Override
    public Zi method03(){

        return null;
    }

}
public class Test01 {
    public static void main(String[] args) {
        Fu fu=new Fu();
        fu.methodFu();
        fu.method();

        System.out.println("=============");
        Zi zi=new Zi();
        zi.methodFu();
        zi.methodZi();
        zi.method();

    }


}

注意事项:

子类重写父类方法之后,权限必须保证大于等于父类权限(权限指的是访问权限)

由大到小   public -> protected ->  默认(不写任何权限修饰符)->private

子类方法重写父类方法,方法名和参数列表一样

私有方法不能被重写,构造方法不能被重写,静态方法不能被重写

子类重写父类方法以后,返回值类型应该是父类方法返回值类型的子类类型

使用场景

功能升级改造,子类需要对父类中已经实验好的功能进行重新改造

三、super和this

1.继承中构造方法的特点

注意:new子类对象时,会先初始化父类(先走父类无参构造方法)

原因:每个构造方法第一行,默认都会有一个super(),不写jvm(虚拟机)自动提供一个

  Super()代表的是父类无参构造

public class Fu {
    public Fu(){
        System.out.println("我是父类中的无参构造");
    }
}
public class Zi extends Fu{

    public Zi(){
        super();
        System.out.println("我是子类中的无参构造");
    }

    public Zi(int i){
        System.out.println("我是子类中的有参构造");
    }
}

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("===============");

        Zi zi1=new Zi(10);
    }
}

2.super的具体使用

概述:代表的是父类引用

作用:可以调用父类中的成员

使用: 调用父类构造方法->在子类中的构造中写

             Super()->调用父类无参构造

             Super(实参)->调用父类有参构造

        

         调用父类成员变量

             Super.成员变量

         调用父类成员方法

              Super.成员方法(实参)

public class Zi extends Fu{
    int num=100;
    public Zi(){
        super();//调用父类中的无参构造
        System.out.println("我是子类中的无参构造");
    }
    public Zi(int num){
        super(10);//调用父类中的有参构造
        System.out.println("我是子类中的有参构造");
    }

    public void method(){
        super.method();//调用父类的method
        System.out.println("我是子类中的method方法");
        System.out.println(num);//子类自己的

        System.out.println(super.num);//调用父类的sum
    }
}
public class Fu {
    int num=10;
    public Fu(){
        System.out.println("我是父类中的无参构造");
    }

    public Fu(int data){
        System.out.println("我是父类中的有参构造");
    }

    public  void method(){
        System.out.println("我是父类中的method方法");
    }
}
public class Test01 {
    public static void main(String[] args) {

        Zi zi=new Zi();

        System.out.println("===============");
        Zi zi1=new Zi(10);
        System.out.println("============");
        Zi zi2 = new Zi();
        zi2.method();

    }
}

3.this的具体使用

概述:代表的是当前对象(那个对象调用this所在的方法,this就代表哪个对象)

作用:区分重名的成员变量和局部变量

     调用当前对象中的成员

使用:调用当前对象的构造:在构造中写

  This():调用当前对象的无参构造

  This(实参):调用当前对象的有参构造

调用当前对象的成员变量:

  This.成员变量名

调用当前对象的成员方法:

        This.成员方法名(实参)

注意:不管是super还是this,只要在构造中使用,都必须在第一行,所以二者不能同时手写出来

public class Person {
    int num=10;

    public Person() {
       // this(10);
        System.out.println("我是person中的无参构造");

    }

    public Person(int data) {
      this();

      System.out.println("我是person中的有参构造");

    }

    public void method(){
        int num=20;
        System.out.println(num);//20
        System.out.println(this.num);
        this.method01();
        method01();
        System.out.println("我是Person中的method方法");
    }

    public  void method01(){
        System.out.println("我是person类中的method01方法");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Person person=new Person();
        System.out.println("========");
        Person person1 = new Person(10);
        System.out.println("==========");
        Person person2 = new Person();
        person2.method();


    }
}

4.继承的特点

(1)继承只支持单继承,不能多继承      public  class  A  extends  B,C{}  ->错误

(2)继承支持多继承

       Public  class  A  extends  B{}

       Public  class  B  extends  C{}  

(3)一个父类可以有多个子类

        Public  class  A  extends  C{}

       Public  class  B  extends  C{}  

(4)构造方法不能继承,也不能重写

私有方法可以继承,但是不能被重写

静态方法可以继承,但是不能被重写

如何为父类中private的成员变量赋值(经验值)

(1)利用set赋值

(2)利用构造方法赋值

四、抽象

抽象类怎么来的:抽取共性的方法,放到父类中,发现方法没办法确定具体实现,因为每个子类对此方法的实现细节不一样,此时方法体说不清,可以定义成抽象方法,抽象方法所在的类一定是抽象类

关键字:abstract

定义抽象方法:

  修饰符  abstract  返回值类型  方法名(参数)

抽象类:public abstract class类名{}

注意:抽象方法所在的类一定是抽象类

           抽象类不一定非得有抽象方法

          子类继承抽象父类时,需要重写父类中所有的抽象方法,不然编译报错

          抽象类不能new对象,只能通过new子类对象调用重写的方法

可以将抽象类看成是一类事物的标准,要求只要属于这一类的,都必须要拥有抽象类中的方法,必须要给我实现,怎么证明拥有了,怎么证明实现了?->重写

  至于这个方法怎么实现,就要看子类重写以后怎么写方法体了

抽象注意事项

  1. 抽象类不能直接new对象,只能创建非抽象子类的对象
  2. 抽象类中不一定非得有抽象方法,但是抽象方法所在的类一定是抽象类
  3. 抽象类的子类必须重写父类中的抽象方法否则编译报错,除非该子类也是抽象类
  4. 抽象类中可以有成员变量,构造,成员方法
  5. 抽象类中可以有构造方法,是供子类创建对象时,初始化父类属性使用的
public  abstract class Employee {
    private String name;
    private int age;

    public Employee() {
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void work();
}
public class Teacher extends Employee {

    public Teacher() {
    }

    public Teacher(String name, int age) {
        super(name, age);
    }

    @Override
    public void work() {
        System.out.println("我在学习");
    }
}
public class Test01 {
    public static void main(String[] args) {

        Teacher teacher = new Teacher("名",1);
        System.out.println(teacher.getName()+".."+teacher.getAge());


    }
}

如有不足,请多多指教,谢谢

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值