JAVA003【多态、代码块、包、权限修饰符、内部类,Object类】

1.什么是多态

同一种事物表现出来的多种形态

2.多态的前提

  • 必须有继承关系或者实现接口关系
  • 必须有方法重写
  • 必须有父类引用指向子类对象

3.多态的格式

  • 父类类名 对象名 =new 子类类名();

4.多态的注意事项:

  • 多态下子类和父类出现同名的成员变量时,访问父类的成员变量();
  • 多态下子类和父类出现同名的成员变量时,访问父类的成员变量();

5.绑定

  • 成员变量的静态绑定:在编译期就确定变量是访问父类的还是子类的
  • 成员方法的动态绑定:在编译期还不确定调用父类的还是子类的方法,是在程序运行过程确定
    • 注意:编译看左边,运行看右边
      • 成员变量编译看左边,运行也看左边(看父类有没有这个方法,没有的话向下转型)
      • 成员方法编译看左边,运行看右边

6.多态的优点

  • 提高代码的复用性
  • 提供代码的维护性

7.多态的缺点

父类引用不能调用子类特有的成员方法

8.多态用于形参或者返回值

1. 多态用于形式参数的好处:可以接受各种子类类型的对象

2. 多态用于方法返回值的好处:可以返回各种子类类型的对象

  • 代码

  • package com.itheima._04多态优缺点;
    
    /**
        目标:理解多态的优点与缺点
    
        讲解:
            1. 多态的优点
                提高代码的复用性
                提高代码的维护性
    
            2. 多态的缺点:父类引用不能调用子类特有的成员方法
    
        小结:
            多态的优点:提高代码的复用性和维护性
    
        思考:多态后如何调用子类特有的功能?
     */
    public class Demo042 {
        public static void main(String[] args) {
            // 买1只?:创建Dog对象
            Dog d1 = new Dog();
            // 让狗吃骨头
           /* d1.eat();
            // 让狗睡觉
            d1.sleep();*/
    
            feedAnimal(d1);
    
            // 又买一只
            Dog d2 = new Dog();
            // 让狗吃骨头
            /*d2.eat();
            // 让狗睡觉
            d2.sleep();*/
    
            feedAnimal(d2);
    
            System.out.println("----------------");
            // 买一只猫
            Cat c1 = new Cat();
            /*c1.eat();
            c1.sleep();*/
            feedAnimal(c1);
    
            // 买一只猫
            Cat c2 = new Cat();
            /*c2.eat();
            c2.sleep();*/
            feedAnimal(c2);
    
    
            Animal d3 = createAnimal(1);
            Animal c3 = createAnimal(2);
        }
    
    
        /**
         * 负责创建动物对象
         * type = 1 狗
         * type = 2 猫
         * @return
         */
        //返回值
        public static Animal createAnimal(int type){
            if (type == 1){
                return new Dog();
            } else if (type == 2) {
                return new Cat();
            }
            return new Tiger();
        }
    
    
        // 喂养动物
        // Animal a = new Dog();
        // Animal a = new Cat();
        //形参
        public static void feedAnimal(Animal a){
            // 让狗睡觉
            a.sleep();
            // 让狗吃骨头
            a.eat();
        }
    }
    

9.基本数据类型的转换格式

  • 小==》大 double a=100;

  • 大==》小 double b=122.5; int c=(int)b

  • 多态转型的分类:

    • 向上转型:父类引用指向子类对象的过程是向上转型的结果
    • 格式:父类类名 变量名=new 子类类名();
    • 向下转型:父类引用转换为子类引用的过程
    • 格式:子类类名 变量名=(子类类名)父类的引用;

10.instanceof关键字的使用

  • 判断父类引用指向哪个子类类型 常用多态之后判断父类引用指向哪个子类类型的对象

  • 格式:boolean b= 父类引用 instanceof 子类类名;

===============================

11.内部类的概述

在一个类中有定义了一个类,在A类定义了B类,A类称为外部类,B类则称为内部类。

12.内部类的分类

  • 静态内部类:定义在外部类的成员位置(有static修饰)
    • 使用格式:class Outer{static class InnerP{} }
  • 实例内部类:定义在外部类的成员位置(没有static修饰)
  • 局部内部类:定义在外部类的成员方法中
  • 匿名内部类:没有名字的类,常用作为方法参数!

13.静态内部

package com.itheima._08静态内部类_了解;

/**
    Tip:静态内部类与外部类的⽤法完全一样。只是访问的时候需要加上外部类.内部类。

    目标:了解静态内部类定义和使用

    讲解:
        1. 静态内部类的使用格式
            class Outer {
                static class Inner{

                }
            }

        2. 静态内部类对象创建格式
            外部类名.内部类名 变量名 = new 外部类名.内部类名(参数);

        3. 静态内部类只能访问外部类的static修饰的成员?这句话对吗?
            正确

    小结:
        1. 静态内部类对象创建格式:
            外部类名.内部类名 变量名 = new 外部类名.内部类名(参数);
 */

class Outer {
    private String name;

    // 静态内部类
    static class Inner{
        // 定义成员变量
        private int age;

        // 定义构造方法
        public Inner(int age) {
            this.age = age;
        }
        public Inner() {
        }

        // 定义成员方法
        public void show(){
            System.out.println("年龄:" + age + ", 姓名:");
        }
    }

    // 外部类方法:创建内部对象
    public void showInfo(){
        Inner inner = new Inner();
        inner.show();
    }

}

public class Demo081 {
    public static void main(String[] args) {
        // 创建静态内部类对象
        /*Outer.Inner i = new Outer.Inner(20);
        // 调用对象调用方法
        i.show();*/

        // 创建外部类对象
        Outer outer = new Outer();
        outer.showInfo();
    }
}

14.实例内部

package com.itheima._09实例内部类_了解;

/**
    实例内部类又称为成员内部类

    目标:了解实例内部类的使用

    讲解:
        1. 实例内部类的定义格式
         class Outer {
              class Inner{

             }
         }

        2. 实例内部类创建对象格式
            外部类名.内部类名 变量名 = new 外部类名().new 内部类名();

        3. 实例内部类的好处
            可以访问外部类的任意成员。

    小结:
        1. 实例内部类创建对象格式:
            外部类.内部类 变量名= new 外部类名(参数).new 内部类名(参数);

        2. 实例内部类的好处
            可以访问外部类所有成员
 */

class Outer {
    // 成员变量
    private static String name;

    public Outer() {
    }

    public Outer(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 实例内部类
    class Inner{
        private int age;

        public Inner() {

        }

        public Inner(int age) {
            this.age = age;
        }

        public void show(){
            System.out.println("年龄:" + age+",外部类name:" + name);
        }
    }
}

public class Demo091 {
    public static void main(String[] args) {
        // 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
        Outer.Inner i = new Outer("jack").new Inner(30);
        // 调用方法
        i.show();
    }
}
package com.itheima._09实例内部类_了解;

/*
    面试题:请在?地⽅写上相应代码,以达到输出的效果

    目标:了解实例内部类如何访问外部类同名的成员变量

    讲解:

    小结:
        如何访问外部类的成员变量:外部类名.this.成员变量名;
 */
public class Demo092 {
    public static void main(String[] args) {
        Body.Heart heart = new Body().new Heart();
        heart.jump();
    }
}

class Body { // 身体    
    private int weight = 30;
    // 在成员位置定义一个类
    class Heart {
        private int weight = 20;

        public void jump() {
             int weight = 10;
            System.out.println("心脏在跳动 " + weight); // 10
            System.out.println("心脏在跳动 " + this.weight);// 20
            System.out.println("心脏在跳动 " + Body.this.weight); // 30

            Body.this.jump();
        }
    }

    public void jump() {
        System.out.println("外部类jump方法...");
    }
}

15.局部内部类

package com.itheima._10局部内部类_了解;

/**
     目标:了解局部内部类的创建和使用

     讲解:
         1. 什么是局部内部类:
            定义在外部类的方法中

         2. 局部内部类的使用:
            只能在方法内部使用

         3. 局部内部类注意事项:
            * 静态方法中的内部类只能访问外部类的静态成员。
            * 非静态方法中的内部类可以访问外部类静态成员和非静态成员。

     小结:
        1. 什么是局部内部类: 定义方法中类

        2. 局部内部类的使用: 只能在定义的方法中使用
 */

class Outer{

    private static String name;

    public static void test(){
        // 定义局部内部类
        class Inner{
            // 定义成员变量
            private int age;

            public Inner(int age) {
                this.age = age;
            }

            public Inner() {
            }

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }

            public void show(){
                System.out.println("年龄:" + age + ",姓名:" + name);
            }
        }

        // 创建局部类对象
        Inner inner = new Inner(40);
        inner.show();
    }
}

public class Demo101 {
    public static void main(String[] args) {
        // 创建外部类对象
        Outer outer = new Outer();
        outer.test();
    }
}

16.11@匿名内部类

package com.itheima._11匿名内部类_重要;

/**
    目标:掌握匿名内部类的语法

    讲解:
        1. 匿名内部类概述
            没有名字的类

        2. 使用匿名内部类的前提条件
            必须有一个已知类或已知接口
            直接创建已知类的子类对象
            直接创建已知接口的实现类对象

        3. 匿名内部类的格式
            new 类名或接口名(){ }

    小结:
        1. 匿名内部类的语法:
            new 类名或接口名(){
                重写方法
            }

 */
public class Demo111 {
    public static void main(String[] args) {
        // 使用匿名内部类:直接创建Animal类的子类对象
        /**
            下面代码等价这两行:
            1. class Xxx extends Animal{
                     @Override
                     public void eat() {
                            System.out.println("吃饭....");
                     }
                }
            2. Animal a = new Xxx();
            3. a.eat();
         */
        Animal a = new Animal(){
            @Override
            public void eat() {
                System.out.println("吃饭....");
            }
        };
        a.eat();

        // 直接创建已经接口的实现类对象
        /**
            下面代码等价两行
            1. class Yyy implements Smoking{
                    @Override
                    public void smoke() {
                        System.out.println("抽烟...");
                    }
                }
            2. Smoking s = new Yyy();
            3. s.smoke();
         */
        Smoking s = new Smoking(){
            @Override
            public void smoke() {
                System.out.println("抽烟...");
            }
        };
        s.smoke();
    }
}

=回顾=

17.代码块

  • 静态代码块 :类中方法外 static{}

    • 特点:类加载的时候会自动执行 只会执行一次
    • 作用:常用执行一次的
  • 实例代码块:每次创建对象都会自动执行一次 {}

package com.itheima._12代码块概述;

/**
     目标:学习静态代码块和构造代码块

     讲解:
        1. 代码块分类
            静态代码块
            构造代码块

        2. 静态代码块概述
            特点:在类加载的时候会自动执行,只会执行1次
            语法:static { }
            作用:常用执行一次性初始化操作

        3. 实例代码块概述
            特点:每次创建对象都会自动执行一次
            语法:{ }

        4. 代码块的定义位置
            类中方法外

    小结
        1. 静态代码块格式: static {}

        2. 实例代码块格式: { }
 */
public class Demo121 {
    public static void main(String[] args) {
        // 创建学生对象
        Student stu01 = new Student();
        Student stu02232323 = new Student();

/*        System.out.println(stu01.getAge());*/
        System.out.println(stu01.getName());
    }
}

18.包

  • 包的概念:包在文件系统中就是文件夹
  • 包的作用:用来解释类命名冲突的问题 将功能相似或相同的类放在一起便于管理
  • 包的定义格式和命名规范:package 包名
  • 包名一般是小写字母 公司域名倒着写 com.itheima

18.导包

  1. 导包方式使用 :
  • import 包名.包名—类名;一个类
  • import 包名.包名.*; 通配符 导入其他包的所有类

​ 2.类全名字符串:当类名一样的时候

  • 包名.包名…类名

19.访问权限

  • private:只能在本类中使用
  • 默认(null)权限:可以在本包下的类访问
  • protected:可以在本包下的类以及其他包有关联的子类访问
  • public:可以在任意包下的任意类访问

20.Object类

  • 特点:最大 所以类的父亲

    • 类object是类层次结构的跟类
    • 每个类都使用object作为超类父类基类
    • 所有类都是直接或者间接继承object类
  • Oject类常用方法

    • String toString();返回该对象的字符串表示

    默认返回格式:类全名字符串@对象在内存中的地址值

    调用时机:

    自动调用:当打印输出对象时系统内部会自动调用

    手动调用:通过对象调用

    • boolean equals(Object obj);

    用来比较两个对象是否相同,是则返回true 否则false

    默认是通过比较两个对象的地址值判断是否相同 除非重写才是比较内容

    ==比较运算符

    基本数据类型:比较两个变量值是否相同

    引用数据类型:比较两个对象的地址值

    @equals方法的作用:

    比较两个对象是否相同 默认是通过地址值比较

    重写equals方法的目的:

    不希望比较地址判断,而是希望比较对象内容判断是否相同

    !!!判断是不是同一个类

    if (obj == null || !(obj instanceof  Student)) return false;
    

    等价于

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        //判断是不是同一个类
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }
    

总结:

package com.itheima._16toString方法;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

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

    public Student() {
    }

    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 void showInfo(){
        System.out.println("name = " + name + ", age = "  + age);
    }

    /*@Override
    public String toString() {
        return "name = " + this.name + ", age = " + this.age;
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    // 重写equals方法:要比较两个对象的内容判断是否相同
    // Object obj = new Student("小泽", 20);
   /* @Override
    public boolean equals(Object obj) {
        // this ==> s1
        // obj ==> s2
        // 判断obj是否是this
        if (this == obj) return true;
        // 判断obj是否为null
        // 判断obj是否是Student对象
        if (obj == null || !(obj instanceof  Student)) return false;
        // 向下转型:将obj转换Student
        Student s2 = (Student)obj;
        // 判断姓名是否相同
        if (!this.name.equals(s2.name)) return false;
        // 判断年龄是否相同
        if (this.age != s2.age) return false;
        // 来到这里说明姓名和年龄都相同
        return true;
    }
*/
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }
}
  • 21.工具类

  • Objects 类概述:是一个工具类 类中的所有方法都是静态方法

  • 常用的工具类 Arrays Objects Collection Math System

  • static boolean isNull(Object obj)判断对象obj是否为null 是返回true

  • static boolean equals(Object a,Object b)比较对象a和对象b是否相同 相同为true

  • Object.equals(x,y) Object.isNull(x)

    • 对于比较优先使用 Object.equals(x,y)
    • s1=null; if(s1!=null){sout(s1.equals(s2))}; 要先判断是否为空
    • sout( Object.equals(s1,s2) ); 推荐使用 因为已经判断了是否为空

22.总结

 - 能够说出使用多态的前提条件
    必须是子父类关系或类实现接口关系
    必须有方法重写
    必须是父类引用指向子类对象

 - 理解多态的向上转型
    父类类型 变量名 = new 子类类型();
    接口类型 变量名 = new 实现类类型();

 - 理解多态的向下转型
    父类引用转换为子类引用的过程
    子类类型 变量名 = (子类类型)父类引用;

 - 能够写出静态代码块的格式
    static {

    }

 - 能够说出权限修饰符作用范围
    private:只能在本类使用
    默认:本包下的类
    protected:本包下的类或子类
    public:任何包下任意类

 - 说出内部类的概念
    在A类中定义了B类,B类就是内部类,A类称为外部类

 - 能够说出Object类的特点:所有类的父类

 - 能够重写Object类的toString方法:
        通过IDEA快速生成即可
        重写目的:在打印对象时希望输出对象的成员变量值

 - 能够重写Object类的equals方法:
        通过IDEA快速生成即可
        重写目的:希望比较内容判断两个对象是否相同。


    1. 多态(重点)
        概念:同一种事物表现出来的多种形态
        前提:
            * 有子父类关系或类实现接口关系
            * 要有方法重写
            * 父类引用指向子类对象
        格式:父类引用指向子类对象:
                父类类型 变量名 = new 子类类型();
                接口类型 变量名 = new 实现类类型();

        好处:提供代码复用性和维护性
        缺点:不能访问子类特有的功能
        应用场景:
            作为方法形式参数:可以接收各种子类类型的数据
            作为方法返回值:可以返回各种子类类型的数据
        转型:
            向上转型:父类引用指向子类对象
            向下转型:将父类引用强制转换为子类引用

        instanceof关键字:
            判断父类引用指向的子类类型
            父类引用 instanceof 子类类型
            Smoking s = new Student();
            boolean b = s instanceof Student

    2. 内部类(匿名内部类重点)
        匿名内部类语法:
            new 类名或接口名(){ }
            直接创建已知类的子类对象或已知接口的实现类对象

    3. 代码块
    4. 包
    5. 权限修饰符

    6. Object特点和常用方法(重点)
    7. Objects工具类
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值