多态,抽象类,接口,在Java中的应用

本文详细探讨了Java中的多态概念,包括其成员访问特点、好处与弊端,以及多态的内存图分析。接着讲解了抽象类的定义、特点,对比了抽象方法和非抽象方法。此外,还深入介绍了接口的使用,类与接口的关系,并对比了抽象类和接口的区别。通过案例和代码演示,帮助读者理解这些概念的应用。
摘要由CSDN通过智能技术生成

目录

多态

  • 多态的概述
  • 多态的成员访问特点
  • 多态的好处和弊端
  • 向上转型和向下转型
  • 多态内存图

抽象类

  • 抽象类的概述
  • 抽象类的成员特点
  • 抽象类的案例

接口

  • 接口的概述
  • 接口的成员特点
  • 类与类,类与接口,接口与接口的关系
  • 抽象类与接口的区别
  • 接口的案例

多态

多态:某一个事物,在不同时刻表现出来的不同状态。
举例:Cat c=new Cat();Animal a=new Cat();猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。动物 d = new 猫();
ps :( 多态中必须有继承关系,要有方法重写,也可以没有方法重写但这样的多态是没有意义的,要有父类应用指向子类对象)
代码演示

public class MyTest {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat();//我没有删除super.eat()所以就有二个吃饭内容
        cat.play();
        System.out.println("-----------------------");
        Animal an = new Cat();//多态演示,要有父类引用指向子类对象
        an.eat();
        System.out.println("-----------------------");
        Gog gog = new Gog();
        gog.eat();
        gog.seedoor();
        System.out.println("--------------------------");
        Gog an2= new Gog();//多态演示,要有父类引用指向子类对象
        an2.eat();

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

    public void play(){
        System.out.println("抓老鼠");
    }
}
class Gog extends Animal{
    @Override
    public void eat(){
        System.out.println("吃骨头");
    }
    public void seedoor(){
        System.out.println("看门");
    }
}

如果采用了多态的这种方式,子类重写了父类的方法,那么我在用父类引用调用方法时,会以子类重写过后的为准

多态中成员访问特点

  • 成员变量:编译看左边,运行看左边。
  • 构造方法:创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
  • 成员方法:编译看左边,运行看右边。
  • 静态方法:编译看左边,运行看左边。

ps:(静态和类相关,算不上重写,所以,访问还是左边的)
代码演示

public class MyTest2 {
   public static void main(String[] args) {
       Fu an = new Zi();
       System.out.println(an.num);//多态的形式访问成员变量访问还是父类成员变量
       an.show();//多态的形式调用方法,首先看这个方法父类里面有没有,如果没有就报错,有的话就访问子类方法
       an.test();//多态的形式调用静态方法还是运行的是父类方法
       Fu.test();
       Zi.test();


   }
}
class Fu{
   int num=100;
public void show(){
   System.out.println("fushow");
}
public static void test(){
   System.out.println("futest");
}
}
class Zi extends Fu{
   int num=120;

   @Override
   public void show() {
       System.out.println("zishow");
   }
   public static void test(){
       System.out.println("zitest");
   }
}

多态的好处与弊端,以及弊端解决方法

  • 提高了代码的维护性(继承保证)
  • 提高了代码的扩展性(由多态保证)
  • 弊端:不能访问子类的自有的方法(但可以通过向下转型可以访问)
    代码演示向下转型
public class MyTest {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat();//我没有删除super.eat()所以就有二个吃饭内容
        cat.play();
        System.out.println("-----------------------");
        Animal an = new Cat();//多态演示,要有父类引用指向子类对象
        an.eat();
      //  an.play()直接访问会报错。通过向下转型就可以访问子类独有的方法
        Cat cat1=(Cat) an ;//向下转型
        cat.play();//这就可以访问
        ((Cat) an).play();//向下转型的另一种方式和上面一样
      
        System.out.println("-----------------------");
        Gog gog = new Gog();
        gog.eat();
        gog.seedoor();
        System.out.println("--------------------------");
        Gog an2= new Gog();//多态演示,要有父类引用指向子类对象
        an2.eat();

    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Cat extends Animal{

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

    public void play(){
        System.out.println("抓老鼠");
    }
}
class Gog extends Animal{
    @Override
    public void eat(){
        System.out.println("吃骨头");
    }
    public void seedoor(){
        System.out.println("看门");
    }
}

案例演示孔子装爹

public class MyTest {
    public static void main(String[] args) {
     孔子爹 k爹 = new 孔子(); //多态:向上转型
        System.out.println(k爹.age)//变量在这里访问父类的成员变量
        k爹.teache();

        孔子 k = (孔子) k爹; //向下转型
        System.out.println(k.age);//变量在这里访问子类的成员变量
        k.playGame(); //调用自己特有的方法

    }
}

class 孔子爹 {
    int age = 60;

    public void teache() {
        System.out.println("讲授JavaSE");
    }
}

class 孔子 extends 孔子爹 {
    int age = 30;


    public void teache() {
        System.out.println("讲授论语");
    }


    public void playGame() {
        System.out.println("玩吃鸡游戏");
    }

}

多态的内存图
在这里插入图片描述
多态分析题代码演示

1

public class DuoTaiTest3 {
    public static void main(String[] args){
        Fu f = new Zi();

       // f.method();这里会出现报错,多态访问子类方法之前会先看父类有这个方法没,如果有就访问子类没有报错
        f.show();
    }
}

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

class Zi extends Fu {
    public void show() {
        System.out.println("zi show");
    }

    public void method() {
        System.out.println("zi method");
    }
}
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();
  }
 }

**输出结果为“爱你”**

抽象类

抽象类:在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
特点:抽象类和抽象方法必须用abstract关键字修饰
格式:abstract class 类名 {},
方法格式:public abstract void eat();
ps:(抽象类不一定有抽象方法,但是有抽象方法一定是抽象类,抽象类可以有构造方法用于访问父类数据时初始化。抽象类不能直接实例化,但是可以按照多态的形式与具体子类进行实例化,这也是多态的一种,抽象类多态,抽象类的子类要莫是抽象类,要莫重写方法)

代码演示

public class MyTest {
    public static void main(String[] args) {
        Animal an=new Cat();
        an.eat();//子类改写过父类的方法
      ((Cat) an).play();//调用子类独有方法
      an.ball();//调用父类方法
        Animal an1=new Dog();
        ((Cat) an).play();//调用子类独有方法
        an1.eat();//子类重写父类的方法
        an1.ball();
    }
}
abstract class Animal{
    public  abstract  void eat();
    public void ball(){
        System.out.println("玩皮球");
    }

}
class Cat extends Animal{//要么在这个类前面加上abstract让这个类变为一个抽象类,要么不加这个类必须改写父类的所有抽象方法使
   // 抽象方法实例化
    @Override
    public void eat() {
        System.out.println("吃鱼");

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

    }
}

抽象类成员特点

  • 成员变量:既可以是变量,也可以是常量。
  • 构造方法:有,用于子类访问父类数据的初始化。
  • 成员方法:既可以是抽象的,也可以是非抽象的。

抽象方法和非抽象方法的比较

  • 抽象方法 强制要求子类做的事情。
  • 非抽象方法 子类继承的事情,提高代码复用性

ps:(一个类如果没有抽象方法,可以定义为抽象类,但是这样没有意义,不能创建对象,)

abstract与private,final ,static , 不能共存没有意义

抽象类员工练习

public class MyTest {
    public static void main(String[] args) {
        Person p = new Jingli();
        p.name = "王经理";
        p.id = 1;
        p.dongzi = 8900;
        System.out.println(p.name);
        System.out.println(p.id);
        System.out.println(p.dongzi);
        Jingli jingli = (Jingli) p;//向下转型调用经理的独有变量
        System.out.println(jingli.jiangjin);//第一种方式
        System.out.println(((Jingli) p).jiangjin);//第二种方式
        p.work();
        p = new Gongren();
        p.name = "小王";
        p.id = 2;
        p.dongzi = 4500;
        System.out.println(p.name);
        System.out.println(p.id);
        System.out.println(p.dongzi);
        p.work();


    }
}

abstract class Person {
    public String name;
    public int id;
    public double dongzi;

    public abstract void work();
}

class Jingli extends Person {
    double jiangjin = 5000;

    @Override
    public void work() {
        System.out.println("管理工作");
    }
}

class Gongren extends Person {
    @Override
    public void work() {
        System.out.println("一线工作");
    }
}
//*结果
王经理
1
8900.0
5000.0
5000.0
管理工作
小王
2
4500.0
一线工作*//




接口

接口:所以,为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,
特点

  • 接口用关键字interface表示 格式: interface 接口名 {}
  • 类实现接口用implements表示 格式: class 类名 implements 接口名 {}
  • 接口不能实例化

ps:(接口的子类可以是抽象类但是 意义不大,可以是具体类要重写接口所有的方法)

接口的成员特点


 - 成员变量;只能是常量,并且是静态的。默认修饰符:public static final,手动给出
 - 构造方法:接口没有构造方法。
 - 成员方法:只能是抽象方法。默认修饰符:public abstract,手动给出,

**代码演示**
public interface MyInterface { //接口中语法特点
   public static final int NUM=100; //公共的静态常量,
    int B=10;//公共的静态常量 //前面有默认的修饰符  public static final
    //接口中没有非抽象方法,全是抽象方法
    public abstract void aa();
    void bb(); //前面有默认的修饰符 public abstract
    //public void hehe(){}; 报错,接口不能有非抽象方法
    //接口中没有构造方法
}
public class MyTest {
    public static void main(String[] args) {
        int num = MyInterface.NUM;
        System.out.println(num);
    }
}
结果
100

代码演示

public class MyTest {
    public static void main(String[] args) {
       Animal a = new Cat();
       a.eat();
       a.play();
      // a=new Dog();
        Dog dog = new Dog();
     a=dog;
        a.play();
       a.eat();
       Fire fire=dog;
       fire.wanhuo();



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

    @Override
    public void play() {
        System.out.println("玩老鼠");
    }
}
class Dog extends Animal implements Fire{
    @Override
    public void wanhuo() {
        System.out.println("玩火");
    }

    @Override
    public void eat() {
        System.out.println("吃骨头");
    }

    @Override
    public void play() {
        System.out.println("玩鸡");
    }
}
interface Fire{
public abstract void wanhuo();
}
吃鱼
玩老鼠
玩鸡
吃骨头
玩火

类与类,类与接口,接口与接口的关系

  1. 类与类:继承关系,只能单继承,可以多层继承。
  2. 类与接口:实现关系,可以单实现,也可以多实现。并且还可以在继承一个类的同时实现多个接口。
  3. 接口与接口:继承关系,可以单继承,也可以多继承。
    代码演示
  public class MyTest {
    public static void main(String[] args) {
        //类跟类的关系
        //类跟类的关系,是继承关系 extends,当自能是单继承

        //类跟接口的关系
        //类跟接口的关系,是实现关系,implments 实现可以多实现,一个类可以实现多个接口
        //我们一个类可以在继承一个类的同时,并且也可以去实现一个或多个接口
        //接口跟接口的关系
        //接口跟接口有继承关系,而且支持多继承
    }
}
abstract class Fu{
    public abstract  void fu();

}

interface A{
    void a();
    void aa();
}

interface  B{
    void b();
    void bb();
}
interface  C{
    void c();
}

class MyClass extends Fu implements A,B,C{


    @Override
    public void a() {

    }

    @Override
    public void aa() {
        //空实现
    }

    @Override
    public void b() {

    }

    @Override
    public void bb() {

    }

    @Override
    public void c() {

    }

    @Override
    public void fu() {

    }
}

interface AA{
    void a();

    void aa();

}
interface  BB{
    void b();

    void bb();

}
interface CC extends AA,BB{
    void cc();

}

class DD implements CC{


    @Override
    public void a() {

    }

    @Override
    public void aa() {

    }

    @Override
    public void b() {

    }

    @Override
    public void bb() {

    }

    @Override
    public void cc() {

    }
}

抽象类和接口的区别

抽象类:

成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象

接口

成员变量:只可以常量
成员方法:只可以抽象

关系类别
类与类
继承,单继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承

设计理念
抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
ps:(JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值