05Java 接口继承多态篇


类的继承

子类可以继承父类原有的属性和方法,也可以增加父类没有的属性和方法,还可以重写父类中的某些方法

知识点:

  • 父类继承
  • 父类方法重写以及修饰权限的访问
  • super关键字
  • 多父类的继承

super关键字

super关键字可以调用父类的属性和方法。
super();语句调用父类构造方法
super.方法名; 语句调用父类的方法
super.属性; 语句调用父类的属性(变量)

以下代码有 方法继承、super关键字的使用、方法重写、构造方法的调用

public class Demo {
    public static void main(String[] args) {
        //实例化
        Computer com = new Computer();
        Notebook not = new Notebook();
        Tablet pan = new Tablet();

        System.out.println("---------继承的使用----------");
        //父类自身方法、属性
        System.out.println(com.Display);
        com.openUp();
        System.out.println("");

        //子类继承方法、属性
        System.out.println(not.Display);
        not.openUp();
        System.out.println("");

        //子类继承方法、属性
        System.out.println(pan.Display);
        pan.openUp();
        System.out.println("");

        //子类自身的方法、属性
        System.out.println(pan.Battery);
        pan.Network();

        //无法调用
//    com.myComputer();
//    pan.myComputer();

        System.out.println("---------方法重写----------");
        not.Function();
        //以重写的方法
        pan.Function();


        System.out.println("---------super关键字的使用----------");
        System.out.println(com.Welcome());
        System.out.println(not.Welcome());
        System.out.println(pan.Welcome());
        System.out.println();
        not.Super();

        System.out.println("---------构造方法调用----------");
        Computer no1 = new Computer("联想电脑");
        Notebook no2 = new Notebook("雷蛇笔记本电脑");
        Tablet no3 = new Tablet("苹果平板电脑");


    }
}

//电脑类
class Computer{//最顶端的类
    String name ;
    //电脑类的构造方法
    public Computer(String name){
        this.name = name;
        //调用时输出电脑name
        System.out.println(name);
    }
    //存在有参数的构造方法,编译器不会自动创建无参数构造方法
    public Computer(){}//手动创建无参构造方法

    String Display = "液晶显示屏";

    public void openUp(){
        System.out.println("打开电脑,请稍等····");
    }

    //限于本类访问的方法 (其他类无法访问、继承的方法)
    private void myComputer(){
        System.out.println("我的电脑");
    }

    public String Welcome() {
        return "欢迎使用";
    }

}

//笔记本电脑类
class Notebook extends Computer {//继承电脑类(父类)
    String name ;
    //笔记本电脑类构造方法
    public Notebook(String name) {
        super(name);//调用电脑类(父类)的构造方法
    }
    //存在有参数的构造方法,编译器不会自动创建无参数构造方法
    public Notebook(){}//手动创建无参构造方法

    //使用super关键字调用电脑类(父类)方法
    public void Super(){
        System.out.println("调用了电脑类属性(Display):"+super.Display);
        System.out.println("调用了电脑类方法openUp()");
        super.openUp();
    }

    public void Function() {
        System.out.println("可折叠电脑!!");
    }

    @Override
    //重写电脑类(父类)的Welcome()方法
    public String  Welcome() {
        //继承电脑类(父类)数据并添加返回
        return super.Welcome()+"笔记本电脑";
    }

}

//平板电脑类
class Tablet extends Notebook {//继承笔记本电脑类
    String name ;
    //平板笔记本电脑类(父类)构造方法
    public Tablet(String name) {
        super(name);//调用笔记本电脑类(父类)的构造方法
    }
    //存在有参数的构造方法,编译器不会自动创建无参数构造方法
    public Tablet(){}//手动创建无参构造方法

    String Battery = "5000毫安";

    public void Network(){
        System.out.println("打开数据");
    }

    @Override
    //重写笔记本电脑类(父类)的Function()方法
    public void Function() {
        System.out.println("不可折叠电脑!!");
    }

    @Override
    //重写电脑类(最顶父类)的Welcome()方法
    public String  Welcome() {
        //继承笔记本电脑类(父类)数据并添加返回
        return super.Welcome()+"平板电脑";//错误示范。(继承笔记本电脑类已修改的数据)
    }

}

运行结果

---------继承的使用----------
液晶显示屏
打开电脑,请稍等····

液晶显示屏
打开电脑,请稍等····

液晶显示屏
打开电脑,请稍等····

5000毫安
打开数据
---------方法重写----------
可折叠电脑!!
不可折叠电脑!!
---------super关键字的使用----------
欢迎使用
欢迎使用笔记本电脑
欢迎使用笔记本电脑平板电脑

调用了电脑类属性(Display):液晶显示屏
调用了电脑类方法(Display)
打开电脑,请稍等····
---------构造方法调用----------
联想电脑
雷蛇笔记本电脑
苹果平板电脑

*注意 : *

  • Java语言中,一个类只可以有一个父类(可以层叠继承)
  • 子类不仅会覆盖父类的方法,还会覆盖父类的属性
  • 父类无参构造方法可自动调用,有参构造方法只能使用 super关键字 调用父类构造方法
  • 用 private 写的方法,其他类无法调用和重写

Object类

Object类是所有类的父类,是最顶层的类,定义类时可省略 extends Object 关键字 ,任何类都可以重写Object类中的方法

Object方法

Object.getClass() 返回对象执行时的Class实例

Object.toString() 以字符串形式返回对象

Object.equals(Object val) 比较两对象的引用是否相等(内容)

equals()方法比较内容,== 比较对象引用的地址

以下代码 Object方法测试

public class Demo{
    public static void main(String[] args) {
        Object[] arr = new Object[4];
        arr[0] = new Object();
        arr[1] = new String("字符串");
        arr[2] = new Demo();
        arr[3] = new Integer(12);

        //getClass()方法
        System.out.println("---------getClass()方法--------");
        for(Object tmp : arr){
            System.out.println(tmp.getClass()); }
        System.out.println();

        //toString()方法
        System.out.println("---------toString()方法--------");
        for(Object tmp : arr){
            System.out.println(tmp.toString()); }
        System.out.println("-----------------");
        for(Object tmp : arr){
            System.out.println(tmp); }
        System.out.println();

        //equals()方法
        Object no1 = new Integer(12);
        Object no2 = new String("12");
        Object no3 = new Integer(12);
        System.out.println("---------equals()方法--------");
        System.out.println(no1.equals(12));
        System.out.println(no1.equals(no3));
        System.out.println(no1.equals(arr[3]));
        System.out.println(no1.equals(no2));
    }
}

运行结果

---------getClass()方法--------
class java.lang.Object
class java.lang.String
class Demo
class java.lang.Integer

---------toString()方法--------
java.lang.Object@10f87f48
字符串
Demo@b4c966a
12
-----------------
java.lang.Object@10f87f48
字符串
Demo@b4c966a
12

---------equals()方法--------
true
true
true
false

对象类型的转换

向上转型

向上转型是子类对象赋值给父类类型的变量 (子类 → 父类)

向下转型

向下转型是将比较抽象的类转换为较具体的类(父类 → 子类)

转换的前提继承父类的子类必须是它本身

以下代码 上下转型以及测试例子

public class Demo {
    public static void main(String[] args) {
        //向上转型
        System.out.println("-----------向上转型---------");
        Animal no1 = new Dog("dog","Jak");
        System.out.println();

        //向下转型
        System.out.println("-----------向下转型---------");
        Animal no2 = new Animal("dog","tom");
        Animal no3 = new Dog("dog","Jak");
        Animal no4 = new Rabbit("Rabbit","Tt");

        //yes 为向下转型成功
//      Dog dg = (Dog)no2;         //no
        Dog dg2 = (Dog)no3;        //yes
//      Dog dg3 = (Dog)no4;        //no

//      Rabbit rm = (Rabbit)no2;      //no
//      Rabbit rm2 = (Rabbit)no3;     //no
        Rabbit rm3 = (Rabbit)no4;     //yes
    }
}

//动物类
class Animal {
    public Animal(String type,String name){
        System.out.println("我的宠物是"+type+" , 名叫:"+name);
    }
}

//小狗类
class Dog extends Animal{

    public Dog(String type, String name) {
        super(type, name);
    }
}

//兔子类
class Rabbit extends Animal{

    public Rabbit(String type, String name) {
        super(type, name);
    }
}

运行结果

-----------向上转型---------
我的宠物是dog , 名叫:Jak

-----------向下转型---------
我的宠物是dog , 名叫:tom
我的宠物是dog , 名叫:Jak
我的宠物是Rabbit , 名叫:Tt

instanceof关键字

instanceof关键字是判断父类对象是否为子类对象的实例,是否继承该子类

myobject instanceof ExampleClass

myobject:某类的对象引用

ExampleClass:某类名称 / 接口名称

以下代码 instanceof关键字的使用

class A{ }

class B extends A{ }

class C extends B implements E{ }

interface E{ }

public class Demo {
    public static void main(String[] ars) {
        C c = new C();
        System.out.println("c是否继承A父类?"+(c instanceof A));

        System.out.println("c是否继承B父类?"+(c instanceof B));

        System.out.println("c是否调用E接口?"+(c instanceof E));

        B b = new B();
        System.out.println("\nb是否继承C父类?"+(b instanceof C));

        System.out.println("b是否继承A父类?"+(b instanceof A));
    }
}

运行结果

c是否继承A父类?true
c是否继承B父类?true
c是否调用E接口?true

b是否继承C父类?false
b是否继承A父类?true

方法重载

方法重载是在同一个类中允许多个同名方法,只要方法参数个数、类型、顺序不同即可!

不同条件:

  • 参数个数的不同
  • 参数顺序的不同
  • 参数类型的不同
  • ...定义不定长的参数个数

以下代码 方法从写及方法的多样性

public class Demo {
    public static void main(String[] args) {
        Demo d = new Demo();
        long a =1;

        d.method(1);
        d.method(1,2);
        d.method(1,a);
        d.method(a,1);
        d.method(1,2,3,4,5,6,7,8);
        d.method(a,2,3,4,5,6,7,8);
    }

    public void method(int a){
        System.out.println("调用了method( int )的方法");
    }

    //参数个数的不同
    public void method(int a,int b){
        System.out.println("调用了method( int , int )的方法");
    }

    //参数类型的不同
    public void method(int a,long b){
        System.out.println("调用了method( int , long )的方法");
    }

    //参数顺序的不同
    public void method(long a,int b){
        System.out.println("调用了method( long , int )的方法");
    }

    //不定长度参数方法
    public void method(int... a){
        System.out.println("调用了method(int...)的方法");
        for (int tmp : a){
            System.out.print(tmp+"\t"); }
        System.out.println();
    }

    public void method(long b, int... a){
        System.out.println("调用了method(long,int...)的方法");
        for (int tmp : a){
            System.out.print(tmp+"\t"); }
    }

}

运行结果

调用了method( int )的方法
调用了method( int , int )的方法
调用了method( int , long )的方法
调用了method( long , int )的方法
调用了method(int...)的方法
1    2    3    4    5    6    7    8    
调用了method(long,int...)的方法
2    3    4    5    6    7    8    

多态

多态可以根据不同类在同一变量,同一方法,执行结果不同的作用

以下代码 多态测试

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

        Animals ton = new Dog("Dog(狗)");
        System.out.println(ton.move());

        Animals Jak = new Rabbit("Rabbit(兔子)");
        System.out.println(Jak.move());

        Animals Yin = new Eagle("Eagle(鹰)");
        System.out.println(Yin.move());

    }
}

//动物类
class Animals {
    String type;
    public Animals(String type){
        this.type = type;
    }
    //移动的方法
    public String move(){
        return(type+"的移动方式:");
    }
}

//狗类 继承 动物类
class Dog extends Animals{
    public Dog(String type) {
        super(type);
    }

    @Override
    //重写移动方法
    public String move(){
        return (super.move()+"跑");
    }
}

//兔子类 继承 动物类
class Rabbit extends Animals{
    public Rabbit(String type) {
        super(type);
    }

    @Override
    //重写移动方法
    public String move(){
        return (super.move()+"跳");
    }
}

//鹰类 继承 动物类
class Eagle extends Animals{
    public Eagle(String type) {
        super(type);
    }

    @Override
    //重写移动方法
    public String move(){
        return (super.move()+"飞翔");
    }
}

运行结果

Dog(狗)的移动方式:跑
Rabbit(兔子)的移动方式:跳
Eagle(鹰)的移动方式:飞翔

抽象类

抽象类一般定义在父类,用来进行继承和多态的处理,该抽象类不能被实例化,需要子类具体化

abstract关键字

abstract关键字是定义抽象类的关键字

public abstract class Text {    }

抽象方法

抽象方法没有方法体,本身是没有意义,需要被继承的子类重写抽象方法

public abstract class Text {
    abstract void textAbstract();
}
  • 抽象方法存在前提,在抽象方法里的类也是抽象类
  • 抽象方法重写才有意义
  • 抽象类不能实例化

以下代码 抽象类和方法的使用

public class Demo {
    public static void main(String[] args) {
        Teachers Tom = new Englishteachers();
        Teachers Jak = new Mathteachers();
//        Teachers Tea = new Teachers();

        Tom.teaching();
        Jak.teaching();
    }
}

//教师抽象类
abstract class Teachers {
    //讲课抽象方法
    public abstract void teaching();
}

//英语老师 继承 教师抽象类
class Englishteachers extends Teachers {
    @Override
    //重写讲课方法
    public void teaching(){
        System.out.println("英语老师,讲课");
    }
}

//数学老师 继承 教师抽象类
class Mathteachers extends Teachers {
    @Override
    //重写讲课方法
    public void teaching(){
        System.out.println("数学老师,讲课");
    }
}

运行结果

英语老师,讲课
数学老师,讲课

个人习题

题目:

动物类(抽象)里有鸟类(抽象)里有小鸡(具体) 和 鹰(具体),写出他们的移动方式,皮毛类型

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

        Birds lan = new Eagle();
        System.out.println("鹰的属性:");
        System.out.print("移动方式:");
        lan.move();
        System.out.print("毛皮样式:");
        lan.Fur();

        System.out.println();
        Birds tom = new Chick();
        System.out.println("小鸡的属性:");
        System.out.print("移动方式:");
        tom.move();
        System.out.print("毛皮样式:");
        tom.Fur();

        System.out.println("\n----------测试--------");

        Animals lan2 = new Eagle();
        System.out.println("鹰的属性:");
        System.out.print("移动方式:");
        lan2.move();
//        System.out.print("毛皮样式:");
//        lan2.Fur();
        /*
            需要向下转型
             ((Eagle) lan2).Fur();
             ((Birds) lan2).Fur();
            才可以调用
        * */
        System.out.println();
        Animals tom2 = new Chick();
        System.out.println("小鸡的属性:");
        System.out.print("移动方式:");
        tom2.move();
//        System.out.print("毛皮样式:");
//        tom2.Fur();
        /*
            需要向下转型
             ((Eagle) lan2).Fur();
             ((Birds) lan2).Fur();
            才可以调用
        * */
    }
}

//动物抽象类
abstract class Animals {
    public Animals() {
        System.out.println("创建了一个动物");
    }
    //移动抽象方法
    abstract public void move();
}

//鸟
abstract class Birds extends Animals {
    public Birds(){
        System.out.println("创建了一个鸟类");
    }
    //毛皮样式抽象方法
    abstract public void Fur();
}

//鹰
class Eagle extends Birds {
    public Eagle() {
        System.out.println("创建了一个鹰");
    }
    @Override
    public void move() {
        System.out.println("飞翔");
    }

    @Override
    public void Fur() {
        System.out.println("羽毛");
    }

}

//小鸡
class Chick extends Birds {
    public Chick() {
        System.out.println("创建了一个小鸡");
    }
    @Override
    public void move() {
        System.out.println("步行");
    }

    @Override
    public void Fur() {
        System.out.println("细毛");
    }

}

运行结果

创建了一个动物
创建了一个鸟类
创建了一个鹰
鹰的属性:
移动方式:飞翔
毛皮样式:羽毛

创建了一个动物
创建了一个鸟类
创建了一个小鸡
小鸡的属性:
移动方式:步行
毛皮样式:细毛

----------测试---------
创建了一个动物
创建了一个鸟类
创建了一个鹰
鹰的属性:
移动方式:飞翔

创建了一个动物
创建了一个鸟类
创建了一个小鸡
小鸡的属性:
移动方式:步行

接口

接口是抽象类的延伸,能批量设置部分子类独有方法

interface关键字

public interface Text {
    public void fangfa(); 
}

interface:定义接口关键字
Text:接口名称

接口 继承与多继承

子接口被调用时,该子接口的父接口全部方法都要继承,都要调用

一个类可以实现多个继承接口,在interface关键字后面逗号分隔即可

注意:

  • 接口中的方法必须定义为 public 或 abstract (抽象方法)形式 ,Java 默认修饰 public
  • 接口定义的字段都是为静态(static)和常量(final)
  • 接口内的方法可以省去 abstract(抽象)关键字
  • 实现多接口时,实例化对象类型为它的本身,否则要转换

以下代码 接口的调用

interface DrawInterface {// 绘制接口
    public void draw();
}

interface Ddc extends DrawInterface{
    public void cs();
}

interface Ddcb {
    public void csb();
}

public class Demo {
    public static void main(String[] args) {
        DrawInterface d = new Qua();
        //调用重写接口方法
        d.draw();

        System.out.println("\n重新测试:");
        //实例化类本身
        Qua q = new Qua();
        //调用类本身的方法
        q.benshen();
        //调用重写接口方法
        q.draw();
        System.out.println();

        DrawInterface d2 = new Square();
        d2.draw();
        System.out.println();


        Ddc d3 = new Triangle();
        d3.draw();
        d3.cs();

        //实例对象本身调用接口方法
        Triangle t = new Triangle();
        t.csb();
    }
}

//三角形类
class Triangle implements Ddc ,Ddcb{    //实现多接口继承

    @Override
    public void draw() {
        System.out.println("绘制三角形");
    }

    @Override
    public void cs() {
        System.out.println("测试继承");
    }

    @Override
    public void csb() {
        System.out.println("测试继承2");
    }
}

//四边形类
class Qua implements DrawInterface {
    @Override
    public void draw(){
        System.out.println("绘制四边形");
    }

    public void benshen(){
        System.out.println("我是四边形");
    }
}

//正方形类 继承 四边形
class Square extends Qua implements DrawInterface {

    @Override
    public void draw() {
        System.out.println("绘制正方形");
    }

}

运行结果

绘制四边形

重新测试:
我是四边形
绘制四边形

绘制正方形

绘制三角形
测试继承
测试继承2

文章作者: 柏竹
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 柏竹 !
评论
  目录