多态,抽象类,接口

多态

多态概述

多态概述:
某一个事物,在不同时刻表现出来的不同状态。

多态的前提

多态的前提

  1. 要有继承关系
  2. 要有方法重写,如果没有方法重写,多态就没有意义。
  3. 要有父类引用指向子类对象。

举例说明多态的前提:

public class MyTest {
    public static void main(String[] args) {
        Animal an=new Cat();	//父类引用执行子类对象
        an.eat();
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Cat extends Animal{	//有继承关系
    @Override	//方法重写
    public void eat() {
        System.out.println("猫吃饭");
    }
}

多态成员访问特点

Fu fu=new Zi();等号左边和等号右边

  1. 访问成员变量,编译看左边,运行看左边
  2. 访问成员方法,编译看左边,运行看右边
  3. 访问静态方法,编译看左边,运行看左边(静态算不上重写,访问还是左边的)
  4. 访问构造方法,创建子类对象时,会先访问父类构造方法,对父类进行初始化。
    可以使用案例:孔子装爹,表示编译和访问看那边
public class MyTest{
    public static void main(String[] args) {
        孔子爹 k=new 孔子();//向上转型
        System.out.println(k.age);//编译看左边,运行看左边--------50
        k.teach();//编译看左边,运行看右边-------讲论语
        孔子 k1= (孔子) k;//向下转型
        System.out.println(k1.age);
        k1.teach();
    }
}
class 孔子爹{
    int age=50;
    public void teach(){
        System.out.println("讲学习知识");
    }
}
class 孔子 extends 孔子爹{
    int age=30;
    @Override
    public void teach() {
        System.out.println("讲论语");
    }
}

多态的好处

  1. 提高代码的维护性(由继承保证)
  2. 提高了代码的扩展性(由多态保证)

多态的弊端以及解决办法

弊端:不能使用子类特有的功能
由多态的弊端引出多态向上转型和向下转型

public class MyDemo {
    public static void main(String[] args) {
        Fu fu=new Zi();	//向上转型
        fu.eat();
        //fu.show();    //由父类引用直接调用子类独有的方法会出现类型转换异常,ClassCastException 类型转换异常
        Zi zi= (Zi) fu; //向下转型,可以调用子类独有的方法
        ((Zi) fu).show();   //快捷调用子类独有的方法,和向下转型一样,
        zi.show();
    }
}
class Fu{
    public void eat(){
        System.out.println("父吃饭");
    }
}
class Zi extends Fu{
    @Override
    public void eat() {
        System.out.println("子吃饭");
    }
    public void show(){
        System.out.println("子类特有的方法");
    }
}

多态的内存图

多态内存图

抽象类

在Java中一个没有方法体的方法定义为抽象方法,类中如果有抽象方法,该类必须定义为抽象类。

抽象类特点

  1. 抽象类和抽象方法必须用abstract关键字修饰
abstract class  类名 {}/	/抽象类格式
public abstract void eat()	;//抽象方法格式
  1. 抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
  2. 抽象类中可以有构造方法,但是抽象类不能实例化,构造方法是用于子类访问父类数据时的初始化
  3. 抽象类不能直接实例化,要按照多态的方式,由具体的子类实例化
  4. 抽象类的子类要么是抽象类,要么重写抽象父类中所有的抽象方法

抽象类的成员特点

  1. 成员变量可以使变量,也可以是常量
  2. 可以有构造方法,创建子类对象时对父类进行初始化
  3. 成员方法既可以是抽象的,也可以是非抽象的
    案例演示抽象类的成员特点
public class MyTest2 {
    public static void main(String[] args) {

    }
}
abstract class AA{
    int num=30;
    public final int NUM=20;		//final修饰的称为常量
    public abstract void show();	//abstract修饰的抽象方法
    public void test(){}		//非抽象方法
}

抽象类的成员方法特性
抽象方法:强制子类做的事情
非抽象方法:子类继承的事情,提高代码的复用性

由具体的员工案例体现抽象类特点

public class MyTest3 {
    public static void main(String[] args) {
        Person person=new Employee();
        person.name="张三";
        person.age=30;
        person.salary=5000;
        System.out.println(person.name+"==="+person.age+"==="+person.salary);
        person.work();
        Person person1=new Manager();
        person1.name="李四";
        person1.age=40;
        person1.salary=20000;
        ((Manager) person1).bonus=5000;
        System.out.println(person1.name+"=="+person1.age+"=="+person1.salary+"=="+((Manager) person1).bonus);
        person1.work();
    }
}
abstract class Person{
    String name;
    int age;
    int salary;		//工资
    public abstract void work();
}
class Employee extends Person{
    @Override
    public void work() {
        System.out.println("一线工作");
    }
}
class Manager extends Person{
    int bonus;		//奖金
    @Override
    public void work() {
        System.out.println("管理工作");
    }
}

abstract与private、final矛盾,与static不能共存,没有意义。

接口

接口就是一个类本身并不具备的功能,可以来定义一些扩展额外的共能,哪些事物,想要具备这些功能,可以去实现这个接口。
接口的特点:

  1. 接口用关键字interface表示
interface 接口名 {}
  1. 类实现接口用implements表示
class 类名 implements 接口名 {}
  1. 接口不能实例化,但是可以用多态的方式来实例化
  2. 接口的子类,可以使抽象类,但意义不大。也可以是具体类,要重写借口中的所有抽象方法。
    可以用案例来表示借口的特点:
//接口用interface表示
interface Myinterface{
    void jump();
}
class Animal{
    public void eat(){

    }
}
//类实现接口用implements实现
class Cat extends Animal implements Myinterface{
    @Override
    public void eat() {
        System.out.println("猫吃饭");
    }

    //子类必须重新接口的抽象方法
    @Override
    public void jump() {
        System.out.println("调高");
    }
}

接口的成员特点

  1. 成员变量只能是常量,而且是静态的
public static final int num=30;//其中public static final是默认的,建议手动写出来
  1. 接口中没有构造方法
  2. 成员方法只能是抽象方法
public abstract void();//其中public abstract是默认的,建议手动写出来

类与接口两两关系

  1. 类与类的关系,是继承关系,只能是单继承,但可以是多层继承
class Fu{}
class Zi extends Fu{ }
  1. 类与接口的关系是实现关系,可以是单实现,也可以是多实现
class Fu2 implements Myinterface,Myinterface2{}
interface Myinterface {}
interface Myinterface2{}
  1. 接口与接口是继承关系,可以单继承,也可以多继承
interface inter{}
interface inter2{}
interface inter3 extends inter,inter2{}

接口与抽象类的区别

  1. 抽象类可以有变量,也可以有常量。接口只能是公共的静态常量。
  2. 抽象类有构造方法,接口没有构造方法。
  3. 抽象类可以有抽象方法,也可以有非抽象方法,接口只能有抽象方法(在JDK1.8之后接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用)
  4. 抽象类被继承体现的是is a的关系,接口被实现体现的是like a的关系。
  5. 抽象类与接口共同点是都不能被直接实例化

用猫狗案例加入跳高功能分析及代码实现:

public class MyTest {
    public static void main(String[] args) {
        Tom tom = new Tom();
        Cat cat=tom;
        cat.name="Tom";
        cat.age=4;
        System.out.println(cat.name+"=="+cat.age);
        cat.eat();
        cat.sleep();
        ((Tom) cat).show();
        Myinterface myinterface=tom;
        myinterface.jump();
        System.out.println("----------------");

        Bigdog bigdog = new Bigdog();
        Dog dog=bigdog;
        dog.name="旺财";
        dog.age=5;
        System.out.println(dog.name+"=="+dog.age);
        dog.eat();
        dog.sleep();
        ((Bigdog) dog).test();
        Myinterface myinterface1=bigdog;
        myinterface1.jump();

    }
}

public abstract class Animal {
    String name;
    int age;
    public abstract void eat();
    public abstract void sleep();
}
public class Cat extends Animal{
    @Override
    public void sleep() {
        System.out.println("猫睡觉");
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");

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

    @Override
    public void sleep() {
        System.out.println("狗睡觉");
    }
}
public class Tom extends Cat implements Myinterface{
    @Override
    public void eat() {
        System.out.println("Tom吃饭");
    }

    @Override
    public void sleep() {
        System.out.println("Tom睡觉");
    }
    public void show(){
        System.out.println("Tom独有的方法");
    }

    @Override
    public void jump() {
        System.out.println("Tom学会了跳高");
    }
}
public class Bigdog extends Dog implements Myinterface{
    @Override
    public void eat() {
        System.out.println("BigDog吃饭");
    }

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

    @Override
    public void jump() {
        System.out.println("Bigdog学会了跳高");
    }
    public void test(){
        System.out.println("Bigdog独有的方法");
    }
}
public interface Myinterface {
    void jump();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值