面向对象-多态

面对对象-多态

步骤:
1.要有继承(或实现)关系

2.要有方法重写

3.父类引用指向子类对象

父类:

package demo3.多态;

public class Animal {
    public void test(){

    }
    public void eat(){
        System.out.println("动物以食为天...");
    }
}

 子类:

package demo3.多态;

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

 测试类:

package demo3.多态;

public class Test {
    public static void main(String[] args) {
        // 对象可以点出什么, 看的是左边声明的类型
        // 父类引用 指向 子类对象
        Animal animal = new Dog();
//        Animal animal = new Animal();
        //运行时绑定:具体执行的方法看右边 new 的是什么类型的对象
        animal.eat();
//        animal.test();
    }
}

父类型变量作为参数时,可以接收任意子类对象

父类:

package demo3.多态2;

public class Animals {
    /**
     * 1.继承,接口实现
     * 2.重写
     * 3.父类引用指向子类对象
     */
    public void eat(){
        System.out.println("Animal 类的eat方法...");
    }
}

子类:

package demo3.多态2;

import demo3.多态.Animal;

public class Dogs extends Animal {
    //Ctrl + O

    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
    public void watch() {
        System.out.println("我还要看家...");
    }
}
package demo3.多态2;

import demo3.多态.Animal;

public class Cats extends Animal {
    @Override
    public void eat() {
        System.out.println("猫正在高兴吃着猫粮...");
    }

}
package demo3.多态2;

public class Util {
    public void eat(Animals animals){
        animals.eat();
    }
}

测试类:

package demo3.多态2;

public class Test {
    public static void main(String[] args) {
        Util util = new Util();
        Animals animals = new Animals();
        util.eat(animals);//Animal 类的eat方法...

        animals = new Cats(); //错误
        util.eat(animals);

        animals = new Dogs();//错误
        util.eat(animals);
    }
}

多态关系中成员变量的使用

需求:子父类中定义了同名的成员变量,如何调用

分析:A : 子父中定义同名属性name并分别初始化值:String name;

B : 在测试类中以多态的方式创建对象并打印name的属性值:Animal animal = new Dog();

C : 在测试类中以普通方式创建对象并打印name的属性值:Dog dog = new Dog();

结论:

成员变量不能重写

成员变量的使用,取决于调用该变量的类型,成员变量不能重写

父类:

package demo3.多态3;

public class Parent {
    String name = "父类中的name";
    public void introductian(){
        System.out.println("父类的自我介绍方法...");
    }
}

 子类:

package demo3.多态3;

public class Child extends Parent{
    String name = "子类中的name";

    @Override
    public void introductian() {
        System.out.println("子类中的自我介绍方法...");
    }
}

 测试类:

package demo3.多态3;

public class Test {
    public static void main(String[] args) {
        //父类引用 指向 子类对象
        Parent parent = new Child();
        //通过父类引用 调用 成员变量,取的是父类的变量值
        System.out.println(parent.name);//父类中的name
        //通过父类引用调用成员方法,具体调用的是什么方法看右边 new 的是什么类型的对象
        parent.introductian();//子类中的自我介绍方法...
        Child child = new Child();
        System.out.println(child.name);//子类中的name
    }
}

 向上转型(自动类型转换)

//子类型转换成父类型
    Animal animal = new Animal();

向下转型(强制类型转换)

//父类型转换成子类型
    Dog dog = (Dog)animal;

注意:

只能在继承层次内进行转换,否则可能造成异常(ClassCastExceptio) 将父类对象转换成子类之前,使用 instanceof 进行检查

public static void main(String[] args) {
        Parent parent = new Child();
        if (parent instanceof Child){
            Child child = (Child)parent;
            child.study("数学");//我正在学习数学
        }else {
            System.out.println("parent 对象 不是 Child 类型,不可以进行强制类型转换!!!");
        }

测试类2:
 

     Child child = new Child();
        boolean b = child instanceof Child;//true
        System.out.println("b = " + b);
        
        boolean b1 = child instanceof Parent;//true
        System.out.println("b1 = " + b1);
        
        boolean b2 = child instanceof Object;//true
        System.out.println("b2 = " + b2);

父类:

package demo3.多态3;

public class Parent {
    String name = "父类中的name";
    public void introductian(){
        System.out.println("父类的自我介绍方法...");
    }
}

子类:

package demo3.多态3;

public class Child extends Parent{
    String name = "子类中的name";

    @Override
    public void introductian() {
        System.out.println("子类中的自我介绍方法...");
    }
    public boolean study(String subject){
        System.out.println("我正在学习" + subject);
        return true;
    }
}

测试类:

package demo3.多态3;

public class Test1 {
    public static void main(String[] args) {
        Parent parent = new Child();
        Child child = (Child)parent;
        child.study("语文");//我正在学习语文
    }
}

final关键字

概念:最终的、最后的

作用:用于修饰类、方法和变量

修饰类:该类不能被继承String,System

修饰方法:该方法不能被重写 不能与abstract共存

修饰变量:最终变量,即常量,只能复制一次

static关键字

作用:

用于修饰类的成员:

成员变量:类变量

成员方法:类方法

调用方式:

类名.变量名

类名.方法名(参数)

static 修饰成员变量

特点:

被本类所有的对象共享

注意:

随意修改静态变量的值是有风险的,为了降低风险,可以同时用final关键字修饰,即公有静态常量(注意命名的变化)。

package demo3.多态;

public class Child extends Parent {
/**
     * 名字
     */
 
   static String name = "儿子";
}
package demo3.多态;

public class Text {
    public static void main(String[] args) {
        System.out.println("name= " + Child.name);//name= 儿子
    }
}

静态方法:

静态方法中没有对象this,所以不能访问非静态成员

静态方法的使用场景

只需要访问静态成员 不需要访问对象状态,所需参数都由参数列表显示提供

package demo3.多态;

public class Child extends Parent {
    /**
     * 名字
     */
   static String name = "儿子";
   int age;
    /**
     * static 修饰的成员变量
     * 1. 通过类名来调用
     * 2. 不可以使用非静态成员(包括非静态成员变量和非静态成员方法),
     * 即不可以使用this关键字和 super关键字
     *
     * @return
     */
    public static String introduce(){
        test();
        return "我是:" + name;
    }
    public static void test(){
        System.out.println(name);
    }

}

package demo3.多态;

public class Text {
    public static void main(String[] args) {
        String introduce = Child.introduce();//儿子
        System.out.println("introduce = " + introduce);//introduce = 我是:儿子
        Child.introduce();//儿子
    }
}

需求:定义静态方法。反转数组中的元素

package demo3.多态3;

public class ReverseDemo {
    //定义一个静态方法,反转输出数组的元素,例如{1,2,3,4,5}
    //6
    //5
    //4
    //...
    //1
    public static void reverse(int[] arr){
        for(int i = arr.length - 1;i >= 0;i--){
            System.out.println(arr[i]);
        }
    }
}

package demo3.多态3;

public class ReverseDemo_Test {
    public static void main(String[] args) {
        int[] nums = {1,2,3,4,5,6};
        ReverseDemo.reverse(nums);
    }
}

接口

概念:

接口技术用于描述类具有什么功能,但并不给出具体实现,类要遵从接口描述的统一规则进行定义,所以,
接口是对外提供的一组规则、标准。
接口的定义:
定义接口使用关键字interface
interface 接口名 {}
类和接口是实现关系,用implements表示

 class 类名 implements 接口名{}

package demo3.接口;

/**
 * 类可以实现接口 通过 implements 关键字
 * 一个非抽象类实现了一个接口,则该类必须实现接口中所有的抽象方法
 */
//Alt + Enter 显示报错
public class Parent implements MyInterface{
    @Override
    public void text() {
        System.out.println("Parent.text");
    }

    @Override
    public void text2() {

    }

    @Override
    public void text3() {

    }
}

注意:
接口不能实现实例化,通过多态的方式实现子类对象
接口继承关系的特点:
接口与接口之间的关系
继承关系,可以多继承,格式:
接口 extends 接口1,接口2,接口3
/**
 * 1.接口中所有的方法默认都是 public abstract
 * 2.abstract 修饰的方法为抽象方法。抽象方法不需要有方法体
 *
 * 3.接口和接口之间是继承关系
 * 4.一个接口可以继承多个接口
 * 5.接口中成员的成员变量 都是 public static final 的常量
 *
 * 接口中 使用 default and static 修饰的方法
 * default 修饰接口中的方法:
 * 1.必须要有方法;
 * 2.调用方式:通过实现类的对象调用
 *
 * static 修饰接口中的方法:
 * 1.必须要有方法体;
 * 2.调用方式:只可以通过 接口名 来调用;
 */

Interface2:

package demo3.接口;

public interface Interface2 {
    void text2();
}

Interface3: 

package demo3.接口;

public interface Interface3 {
    void text3();
}

 MyInterface:

package demo3.接口;
public interface MyInterface extends Interface2,Interface3{
    int age = 18;//final
    void text();

    default void defaultMethod(){
        System.out.println("MyInterface.defaultMethod");
    }
    static void staticMethod(){
        System.out.println("MyInterface.staticMethod");
    }
}

测试类:

package demo3.接口;

public class Test {
    public static void main(String[] args) {
        Parent parent = new Parent();
        System.out.println("parent.age = " + parent.age);//parent.age = 18
        System.out.println(parent.age);//18
        System.out.println(MyInterface.age);//18
        parent.defaultMethod();//MyInterface.defaultMethod
        MyInterface.staticMethod();//MyInterface.staticMethod
    }


}

接口成员的特点

接口成员变量的特点
接口没有成员变量,只有公有的,静态的常量:
public static final 常量名 = 常量值;
接口成员方法的特点
JDK7 及以前,公有的、抽象方法:
public abstract 返回值类型 方法名();
JDK8 以后,可以有默认方法和静态方法:
public default 返回值类型 方法名(){}
static 返回值类型 方法名() {}
JDK9 以后,可以有私有方法:
private 返回值类型 方法名(){}
接口构造方法的特点
接口不能够实例化,也没有需要初始化的成员,所以接口没有构造方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值