JavaSE 多态 抽象类 接口 system类 object类等
本文最后更新于 755 天前,其中的信息可能已经有所发展或是发生改变。

 

一:前言:

最近趁着闲暇时间入门了Java,别说,学过其他语言是真滴快,一路二倍速加速,但是到了多态这个地方,发现逻辑啥的还是挺混乱的,于是乎。。。。。这篇文章就出现了!!!但是我不建议学语言记太多笔记,毕竟~~~无招胜有招~

什么是多态?

1.1多态概述
同一个对象,在不同时刻表现出来的不同形态

举例:猫
我们可以说猫是猫:猫cat = new猫();
我们也可以说猫是动物:动物animal = new猫();这里猫在不同的时刻表现出来了不同的形态,这就是多态

多态的前提和体现:

有继承/实现关系有方法重写
有父类引用指向子类对象

 

 

二:多态的优缺点:

 

一共有四个类:

Animal

AnimalDemo

AnimalOperator

Cat

 

package duotai;
//一个动物的大类
public class Animal {
    public void eat(){
        System.out.println("动物吃东西");
    }
}

package duotai;

//猫类 并且重写方法
public class Cat extends Animal {
    @Override 
    public void eat(){
        System.out.println("猫吃骨头");
    }

   public void lookdoor(){
        System.out.println("猫看门");
    }

} 

package duotai;

//动物操作类
public class AnimalOperator {
    public void userAnimal(Cat c){
        //相当于 Cat c = new Cat()
        c.eat();
    }
}

 

package duotai;

//测试类

public class AnimalDemo {
    public static void main(String[] args) {
            //创建动物操作类的对象,调用方法
            AnimalOperator ao = new AnimalOperator();
            Cat c = new Cat();
            ao.userAnimal(c); //把猫类型传给了ao
    }

}

但是每次这样AnimalOperator都要去添加一个方法去调用,很麻烦,于是

 

package duotai;

//动物操作类
public class AnimalOperator {

    public void userAnimal(Animal a){
      //相当于Animal a = new Cat(); 编译看左边,有eat方法,运行看右边,cat里面重写了cat方法所以输出重新后的方法
     //如果有Dog类 那么下面不用加方法,直接相当于Animal a = new Dog(); 但是必须得重写过方法
        a.eat();
        a.lookdoor(); //报错~~~多态的形式不能访问具体的子类所特有的功能 
    }
}

这样就简化了编写,不用写多的方法,得出 多态 提高了程序的扩展性,具体的体现是:在定义方法的时候使用父类型作为参数,在将来使用的时候是使用具体的子类型

缺点是:多态的形式不能访问具体的子类所特有的功能

 

 

 

 

其中被注释的 c.playGame()是无法调用的,于是我们可以强制转换c为一个子类的对象

 

抽象的方法没有方法体。需要注意的是在抽象类中既可以有抽象方法,也可以有普通方法,注意抽象方法是没有方法体的(也就是方法后面是没有大括号的)。凡是继承这个抽象类的实体子类,都必须要实现这个抽象方法。

我们总结一下抽象类的特点:

(1)抽象类不能被实例化

(2)构造方法 和 static 方法不能是抽象的

(3)父类的抽象方法往往在子类中实现

(4)抽象类可以具有指向子类对象的对象引用

 

三:接口的特点

接口用关键字interface修饰

public interface接口名丹类实现接口用implements表示

public class 类名 implements 接口 名

接口不能实例化
接口如何实例化呢?

参照多态的方式,通过实现类对象实例化,这叫接口多态。多态的形式:具体类多态,抽象类多态,接口多态

多态的前提:

有继承或者实现关系;有方法重写;

有父(类/接口)引用指向(子/实现)类对象接口的实现类
要么重写接口中的所有抽象方法要么是抽象类

 

 

例子:

思路:
定义接口(Jumpping)

成员方法:跳高();定义抽象动物类(Animal)

成员变量:姓名,年龄;构造方法:无参,带参;成员方法: get/set方法,吃饭(;③定义具体猫类(Cat),继承动物类,实现跳高接口

构造方法:无参,带参;成员方法:重写吃饭(){.….},重写跳高方法({.….}④定义狗类(Dog),继承动物类,实现跳高接口

构造方法:无参,带参;成员方法:重写吃饭({….},重写跳高方法({…]

 

package itheima_01;

//接口
public interface Jumpping {
    public abstract void jump();
}

 

package itheima_01;
//动物类
public abstract class Animal {
        private String name;
        private int 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 Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Animal() {
    }

    public abstract void eat();
}

 

 

package itheima_01;
//猫类
public class Cat extends Animal implements Jumpping{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

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

    public Cat() {
    }

    @Override
    public void jump() {
        System.out.println("调高");
    }
}

 

 

package itheima_01;

public class AnimalDemo {
    public static void main(String[] args) {
        //创建对象,调用方法
        Jumpping j = new Cat();
        j.jump();
        Animal a = new Cat();
        a.setAge(5);
        a.setName("加菲");
        System.out.println(a.getAge()+a.getName());
        a.eat();
        //报错
        //a.jump  故接口只能调接口里的方法 抽象类只能调抽象类里 的方法

        //带参构造
        a = new Cat("加菲",5);
        System.out.println(a.getAge()+a.getName());
        a.eat();

        //cat继承了动物类也实现了接口,故更多时候用具体的类
        Cat c = new Cat();
        c.setAge(5);
        c.setName("加菲");
        System.out.println(c.getAge()+c.getName());
        //都可以调用
        c.eat();
        c.jump();

    }
}

1.抽象类和接口的区别

成员区别:

抽象类:
变量,常量;有构造方法;有抽象方法,也有非抽象方法
接口:
常量;抽象方法

关系区别:

类与类
继承,单继承
类与接口

实现,可以单实现,也可以多实现

接口与接口

继承,单继承,多继承

设计理念区别:

抽象类
对类抽象,包括属性、行为
接口
对行为抽象,主要是行为

重点来啦~~~:抽象类是对事物的抽象,接口是对行为的抽象

 

 

 

 

如下:

package itheima02;
//人大类
public abstract class Person {
    private String name;
    private int age;

    public abstract void eat();

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

    public Person() {
    }

    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;
    }
}

 

package itheima02;

//说英语的接口
public interface SpeakEnglish {
    public abstract void speak();
}
package itheima02;
//运动员类

public abstract class Player extends Person{
    public abstract void study();

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

    public Player() {
    }
}
package itheima02;

public class PingPongPlayer extends Player implements SpeakEnglish{

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

    @Override
    public void study() {
        System.out.println("我要学乒乓球");
    }

    @Override
    public void eat() {
        System.out.println("我要吃粥");
    }

    @Override
    public void speak() {
        System.out.println("我要学英语");
    }
}
package itheima02;
//测试
public class PersonDemo {
    public static void main(String[] args) {
        PingPongPlayer ppp = new PingPongPlayer();
        ppp.setName("ooo");
        ppp.setAge(18);
        System.out.println(ppp.getAge()+ppp.getName());
        ppp.eat();
        ppp.speak();
        ppp.study();

        BasketballPlayer bp = new BasketballPlayer();
        bp.setAge(10);
        bp.setName("啊");
        System.out.println(bp.getAge()+bp.getName());
        bp.eat();
        bp.study();
    }
}

嫌麻烦就差不多得了~~~~~~~~~~~~~~

 

 

2.接口名作为形参和返回值

 

 

以接口作为形参,由于不能直接调用,需要创建一个具体类去重写方法在new一个新对象调用,如果一个方法的形参是接口名,那么它其实要的是该接口的实现类对象

 

作为返回值时

 

 

以多态的形式创建了接口的对象

 

3.内部类

 

按照内部类在类中定义的位置不同,可以分为如下两种形式,其实也就是不想让外部能访问到内部的内容

在类的成员位置:成员内部类
在类的局部位置:局部内部类

 

成员内部类

 

即创建外部类的对象,调用method方法就可以调用内部类的show方法了

局部内部类:

 

外界无法直接访问,是要通过外部类的对象 调用method方法来间接访问

 

匿名内部类,属于局部内部类的一种

前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类

本质:是一个继承了该类或者实现了该接口的子类匿名对象

 

 

调用 method方法,可以访问这个内部类,其中 Inter 是一个接口

 

对象调用show方法,即可输出内容,但是呢,这样多次调用会很麻烦

 

于是:既然这个整体是一个对象,那么应该有返回值类型,因为new inter ,这个整体看成是一个Inter的实现类对象,按照多态的形式,赋值给Inter这个接口

 

这样于是就可以多次调用啦~~~~

 

那么匿名内部类在实际开发中怎么应用呢?

例如我写一个调高的接口,

 

demo中 因为形参是接口,所有每次都需要实现类,这样会麻烦,于是使用匿名内部类,因为匿名内部类的本质就是一个对象,并且是实现该接口的对象

 

 

这样就不用多写两个类并且new对象了~~~~~

 

 

三:System类和Object的个例

 

 

 

重点学习toString和equals方法

下面有一个例子:

取的是对象的地址,查看方法对应源代码,复制到 下面

 

可以看到 println(s)传递s到了 object x  之后Object x 传递到 Object obj ,,if判断中 obj不会是null,于是调用toString方法

 

 

建议所有子类覆盖此方法~~~于是 重写

 

 

equals方法:

那么如何单独的比较内容呢?即姓名年龄,

即重写equals方法

解析这段代码:

this — s1

o — s2

第一个if 比较地址,相同返回true

 

第二个if: 如果参数o为null 返回false || 判断两个对象是否来自同一个类,不同返回false

 

然后进行向下转型

 

第三个if 比较年龄

第四个if 比较姓名 其中 name 是String类型的,所以用equals比较名字是否相等

总结:

 

四:拆箱,装箱

 

 

 

评论

  1. xiaoyu 博主
    Windows Chrome
    2年前
    2021-6-02 16:43:37

    我吐了,这个代码插件 不咋地呀

  2. 123
    Android Chrome
    2年前
    2021-6-08 0:01:54

    写的好好吖 膜拜大佬

    • xiaoyu 博主
      Windows Chrome
      2年前
      2021-6-08 0:10:13

      不是啦~

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇