Java中final和多态调用成员变量、成员方法的应用(基础详解)

final

    final(关键字)
    1.修饰方法 作用: 被修饰的方法 不能被重写
    2.修饰变量 final 修饰引用数据类型时 对象中的成员变量值是可以被修改的
             被final修饰的对象 的地址 不能改变(不能重新指向)
    3.修饰类 作用 :被修饰的类 不能被继承

    例如:

    public static void main(String[] args) {
        /*
        ClassA a = new ClassA();
        a.fun();

        //final 修饰的基本数据类型的变量 不能被 重新赋值
        final int num = 10;
        System.out.println(num);
        num = 15;
        */

        // final 修饰引用数据类型时 
        // 对象中的成员变量值是可以被修改的
        final ClassA a1 = new ClassA();
        // 修改成员变量
        a1.num = 10;
        a1.num = 15;

        // 被final修饰的对象 的地址 不能改变(不能重新指向)
        //a1 = new ClassA();
        System.out.println(a1.num);
    }

        class ClassA{
        // num 创建对象时 有默认的初始值 是0
        // 但是这个初始值 是无效的
        int num;

        public final void fun() {
            System.out.println("我是ClassA的fun方法");
        }
    }

        class ClassB extends ClassA{
            //被final修饰的方法 不能被重写
        //  public void fun() {
        //      
        //  }
        }
    final修饰成员变量 该成员变量 必须有 有效的初值(如果你不赋值的话 系统也会给你一个默认值)
    (但是这个默认值是无效的)
    (所以用final修饰成员变量时 必须要给成员变量赋值)

    被final修饰的成员变量 程序中不能被修改 相当于常量

    被final修饰的成员变量的使用场景:
        一般会与 public static 连用

    命名规范:
        纯大写 多个单词用下划线分开

        例如:
        public static void main(String[] args) {
        System.out.println(ClassC.MAX_VALUE);
    }

    class ClassC{
        public static final int MAX_VALUE = 10;
    }

    public void fun(){
        System.out.println(MAX_VALUE);
    }

    这里 打印出来的 是 10;


    例如2:

    public void fun() {
        final int num = 15;//局部变量用final修饰时

        num = 15 //这里就会报错 因为用final修饰时
                     // num的值不能被修改

    }

    例如3:
    public void fun(final int i) {//final修饰参数
        i = 15;//这里会报错
               //当final修饰参数时 
               //参数的值也不能被修改
    }

多态

    多态规则: 一种事物的多种形态
    多态前提:
        1.类与类之间 要产生联系 继承关系
        2.要有方法重写(没有方法重写 多态的意义不大)
        3.核心:父类引用指向子类空间(声明方式)

        例如:
            public class Demo {
        public static void main(String[] args) {
            //本类的引用指向 本类的对象空间
            //Cat cat = new Cat();

            //父类的引用 指向 子类的空间
            Animal cat = new Cat();
            cat.shout();
            // 使用多态 来声明子类对象
            Animal dog = new Dog();
            dog.shout();
        }
    }

    class Animal{
        String name;
        String kind;

        public void shout() {
            System.out.println("我是动物叫出声");
        }

        @Override
        public String toString() {
            return name + kind;
        }
    }

    class Cat extends Animal{

        public void shout() {
            System.out.println("我是猫叫喵喵喵");
        }
        @Override
        public String toString() {
            return super.toString();
        }
    }

    class Dog extends Animal{
        public void shout() {
            System.out.println("我是狗叫汪汪汪");
        }
        @Override
        public String toString() {
            return super.toString();
        }
    }

多态调用成员变量

    public class Demo{
        public static void main(String[] args) {
            //多态的形式创建对象
            Father f = new Son();
            System.out.println(f.num)//这里打印的是10
            //当使用父类引用 指向子类空间的时候
            //父类的引用 只能访问到 
            //子类 空间中 属于 父类的那部分(super访问的部分)

            //当本类引用指向本类空间的时候
            //本类的引用可以访问到 整个 空间
            //如果父类中 没有 num 这个变量
            //那么就会直接报错
        }
    }
    class Father{
        int num = 10;

        public void print() {
            System.out.println("我是Father类的 print方法");
        }
    }

    class Son extends Father{
        int num = 20;

        public void print() {
            System.out.println("我是Son类的 print方法");
        }
    }

多态调用成员方法

    public class Demo{
        public static void main(String[] args) {
            //多态的形式创建对象
            Father f = new Son();
            //f 调用 print 这个方法
            f.print()//这里打印的是"我是Son类的print方法"
            //因为f是指向 Son()这个地址的
            //如果是调用方法 则会使用就近原则
            //如果子类中没有这个方法 那么就回去父类中寻找
        }
    }
        class Father{

        public void print() {
            System.out.println("我是Father类的 print方法");
        }
    }

    class Son extends Father{
        int num = 20;

        public void print() {
            System.out.println("我是Son类的 print方法");
        }
    }

多态 调用成员变量 和 调用 成员方法 在内存中的表现

多态  调用成员变量  和 调用 成员方法 在内存中的表现

    举例:


    //人 说话(聊天)
    //骗子 说话(洗脑) 打人

    public class Demo {
    public static void main(String[] args) {
        //使用多态的形式创建对象
        //骗子把自己的逼格升高 伪装成了 一个人
        //向上转型
        Person p = new Liar();
        // 调用子类的方法
        p.speak();
        // 调用子类特有方法
        // 多态下 创建出来的对象 
        // 是不能直接调用子类的特有方法
        // p.hit();
        // 需要 把这个对象 进行 向下转型(相当于 强制类型转换)
        // 注意: 必须要是这个类型 才能进行强转
        // 先有向上转型 才会有 向下转型
        Liar liar = (Liar)p;
        liar.hit();
        //调用重写父类方法 和 子类特有方法
    }
}

    class Person{

        public void speak() {
            System.out.println("说话");
        }
    }
    // 骗子类
    class Liar extends Person{
        public void speak() {
            System.out.println("洗脑");
        }

        public void hit() {
            System.out.println("打到死为止");
        }
    }

    多态的优势:
        1.代码维护性强(这条建立在 继承的基础上)
        2.方法的扩展性强(核心好处)

        多态的弊端:
        使用多态声明对象的时候 无法直接调用子类的特有方法
        只能通过向下转型后 才能使用子类特有的方法
    /*
     * 需求:
     * 武器类  打 挥舞武器
     * 刀类    打  挥舞刀 —  砍人
     *        练功  练刀
     * 棍类    打  挥棍 —— 敲人
     *        练棍  耍棍
     * main方法 封装一个创建刀的方法  在方法中 调用 挥舞刀方法
     * 
     */
    public class Demo06 {


        // 接收的时候 相当于 Weapons weapons = new weapons(); 向上转型
        // 这时候 只要是 武器类的 子类 都能使用这个方法
        //用这个方法写可以避免 如果很多人都要使用武器
        //就不用 创建很多 多态调用方法 可以节省很多代码量
        public static void makeWeapons(Weapons weapons) {
            weapons.fight();
            //判断是不是 刀的类型
            //如果是刀 再进行向下转型
            //weapons instanceof Broadsword 判断weapons是不是Broadsword
            if (weapons instanceof Broadsword) {
                //向下转型
                Broadsword broadsword = (Broadsword) weapons;
                //调用特有的 方法
                broadsword.practice();
            }
            // 判断 是不是 棍
            if (weapons instanceof Stick) {
                Stick stick = (Stick) weapons;
                stick.practice();
            }
        }



        public static void main(String[] args) {
            makeWeapons(new Broadsword());
            makeWeapons(new Stick());
        }
    }

    class Weapons{
        public void fight() {
            System.out.println("挥舞武器");
        }
    }

    class Broadsword extends Weapons{
        @Override
        public void fight() {
            System.out.println("砍人");
        }

        public void practice() {
            System.out.println("练屠龙刀  ");
        }
    }

    class Stick extends Weapons{
        @Override
        public void fight() {
            System.out.println("敲人");
        }

        public void practice() {
            System.out.println("练五郎八卦棍");
        }

    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值