JAVA面向对象之 方法重写、多态与抽象类的基础知识

JAVA面向对象之 方法重写、多态与抽象类的基础知识

1. 方法重写

  • 方法重写:当子类出现了和父类一模一样(方法名,参数列表,返回值)的一个方法,就会发生方法覆盖现象,子类的方法会覆盖父类方法;
  • 子类对父类的不满意可以重写
  • 当不想完全覆盖父类功能时,可以使用 super.方法名()//沿袭父类功能
public class Person {
    int age;
    String name;
    public void sports(){
        System.out.println("我爱运动");
    }

    public void study(){
        System.out.println("我爱学习");
    }

}

public class Student extends Person {
    public void study(){
        System.out.println("我爱学习敲Java");
    }
}

public class Teacher extends Person{
    public void study(){
        @Override
        super.study();//沿袭父类功能
        System.out.println("我爱学习写教案");
    }

}

public class Test {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        t.age=20;
        t.name="老沈";
        t.sports();
        t.study();
        System.out.println(t.name+t.age);
        Student S = new Student();
        S.age=20;
        S.name="老沈";
        S.sports();
        S.study();
        System.out.println(S.name+S.age);
    }
}
/*
我爱运动
我爱学习 //沿袭父类功能
我爱学习写教案
老沈20


我爱运动
我爱学习敲Java
老沈20
*/

1.2 方法重写注意事项

  • 子类不能重写父类私有方法,私有方法都不能继承,何谈重写?
  • 子类重写父类方法时,方法的权限修饰符,要比父类的高或一样
  • 构造方法不参与重写
  • 静态方法不参与重写
  • 父类final修饰的方法,子类不能重写

1.3 方法重载与方法重写区别

  • 方法重载:允许一个类中,可以定义多个同名方法,知意他们的参数列表不同(形参个数,形参类型)
  • 方法重写:发生在继承环境中,子类可以提供一个与父类一模一样的方法(方法名,形参列表,返回值),就会发生子类方法,覆盖父类方法现象。

入口类:只是作为程序入口,一般不会在入口类里面提供除了main方法之外的方法,只需要提供main方法即可,在main方法中,使用其他类

1.4 final关键字

  • final:最终的,可以修饰变量,成员方法,类
  • final:修饰变量,此方法就为常量
  • final:修饰成员方法,此方法不能被重写,可以继承;
  • final:修饰引用数据类型,指的是地址值不能再更改;
  • final:修饰类,此类不能被继承;
  • final:修饰引用数据类型,指的是地址值不能再更改
public static void main(String[] args) {
        //final 修饰的基本数据类型,指的是变量的值,不可再更改了
        final int num = 100;
        //final 修饰的引用数据类型,指的是,这个地址值,不能再更改。
        final Scanner scanner = new Scanner(System.in);
        // scanner=new Scanner(System.in);
    }

2. 多态

  • 概念:指的是一种事物,在不同时刻所表现出的不同状态

例:

猫 他是猫类的一种 	Cat cat=new cat();
猫 他是动物类的一种	Animal an=new cat()

多态的前提:

  • 要有继承,如果没有继承,多态无从谈起;
  • 要有方法重写,如果不重写,虽然语法不报错,但就失去了多态的意义;
  • 父类引用指向子类对象 Animal an=new Cat()

2.1多态的好处

  • 提高了复用性,提高了代码的维护性 扩展性(有利也有弊)

多态就是向上转型

**多态的形式访问成员变量:**编译看左边,运行也看左边,左边是父,右边是子类.

**多态的形式访问成员方法:**编译看左边,运行也看右边,左边是父,右边是子类,假如子没有被重写,就运行父的;

多态形式访问静态方法,访问的父类的静态方法,子类静态不需要被重写;

练习:孔子装爹

/*
 孔子爹,是一个著名的Java讲师,张三,慕名前来,请孔子爹去他家里给他上课,孔子爹就去了
只留孔子一人在家,这个时候,李四也来孔子家里,请孔子爹去讲课。孔子爹不在家,
孔子不想失去这个学生,他就得乔装打扮一番,扮成他爹的模样,去给李四讲课,孔子只会讲论语。
 讲完之后,孔子回到家里感觉,装爹他累了,他想做回他自己,然后愉快的玩了一把游戏。
 */
 
 public class Kz extends KzDad{
    int age=30;
    public  void teach(){
        System.out.println("讲授论语");
    }
    public void playgame(){
        System.out.println("玩游戏");
    }
}

public class KzDad {
    int age=60;
    public  void teach(){
        System.out.println("讲授JAVA");
    }
}

public class FouthLX {
    public static void main(String[] args) {
      KzDad kd =new Kz();
        System.out.println(kd.age);
        kd.teach();
        System.out.println("+++++++++++++++++++++++++++++++++++++");
        Kz K=(Kz) kd;
        K.playgame();
    }
}

2.2多态的弊端

  • 不能直接访问子类特有的成员,如果要访问,需要向下转型: Son son=(son) f;

不能瞎转,父子之间转,子与子之间不能转;

//向下转型
public class MyTest {
    public static void main(String[] args) {
        Father f = new Son(); //多态,其实就是向上转型。
        f.show();
        //f.hehe();//不能直接访问子类特有的方法。
        //向下转型
        Son son = (Son) f;
        son.hehe();
    }
}

class Father {

    public void show() {
        System.out.println("fu show");
    }
}

class Son extends Father {
    @Override
    public void show() {
        System.out.println("zi show");
    }

    public void hehe() {
        System.out.println("子类特有的方法");
    }
}

练习2:多态传递

class A {
    public void show() {
        show2();
    }

    public void show2() {
        System.out.println("我");
    }
}

class B extends A {
    public void show2() {
        System.out.println("爱");
    }
}

class C extends B {
    public void show() {
        super.show();
    }

    public void show2() {
        System.out.println("你");
    }
}

public class DuoTaiTest4 {
    public static void main(String[] args) {
        A a = new B();
        a.show(); //爱

        B b = new C();
        b.show(); //你
    }
}

练习3:多态构造方法,值传递,调用子类特有方法

public class Father {
    int num = 100;

    public Father() {
        System.out.println("父类构造方法执行了");
    }

    public void show() {
        System.out.println("fu show");
    }
}


public class Son extends Father {
    int price = 500;

    public Son() {
        System.out.println("子类构造方法执行了");
    }

    @Override
    public void show() {
        System.out.println("zi show");
    }

    public void hehe() {
        System.out.println("hehe");
    }
}


public class MyTest {
    public static void main(String[] args) {
        Father father = new Son();
        System.out.println(father.num);
        father.show();
        Son son = (Son) father;
        System.out.println(son.price);
        son.hehe();

    }
}

2.3 多态的内存解析

public class Father {
    int num = 100;

    public Father() {
        System.out.println("父类构造方法执行了");
    }

    public void show() {
        System.out.println("fu show");
    }
}

public class Son extends Father {
    int price = 500;

    public Son() {
        System.out.println("子类构造方法执行了");
    }

    @Override
    public void show() {
        System.out.println("zi show");
    }

    public void hehe() {
        System.out.println("hehe");
    }
}

public class MyTest {
    public static void main(String[] args) {
        Father father = new Son();
        System.out.println(father.num);
        father.show();
        Son son = (Son) father;
        System.out.println(son.price);
        son.hehe();


    }
}
  • 上述代码在内存中是如何运行

多态内存图分析

3.抽象类

  • 一旦类中有抽象方法,那么类也就是抽象的
  • abstract 抽象的,可以修饰类和方法
  • 抽象方法,只需要给出所有子类的共性功能的声明,而不给出功能的具体实现,而是交由子类,按照自身的差异,去重写
  • 父类的抽象方法,会强制子类必须重写.
  • 抽象方法,强制子类重写
  • 非抽象方法,就是让子类继承下去直接用,当然子类可以重写,但是不带有强制性.
  • 抽象类里面既可以定义抽象方法,也可以定义非抽象方法
public abstract class Animal {
    public abstract void eat();

    public abstract void sleep();

    public void show() {
        System.out.println("fu show");
    }
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}


public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗爱吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗爱在狗窝里数据");
    }

}

抽象类的特点

一但一个类有了抽象方法,此类必须为抽象类;

这个类的他没有定义抽象方法,可以把这个抽象类;

抽象类不能直接创建对象

抽象类不能直接创建对象,我们可以通过多态的方式,间接实例化这个抽象类;

作为抽象类的子类,他有两种选择:

1.子类必须重写抽象类中的所有抽象方法

2.你也变为抽象类:

抽象类中有构造方法. 作用:让子类可以通过多态的方式,简介实例化这个抽象类

@Override
public void eat() {
System.out.println(“狗爱吃骨头”);
}

@Override
public void sleep() {
    System.out.println("狗爱在狗窝里数据");
}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值