day03——面向对象高级

YangeIT大约 27 分钟JavaSE进阶多态final继承

day03——面向对象高级

学习目标

各位同学,前面两天我们已经把面向对象最主要的内容学习完了,剩下的这些语法知识学完,那么Java语法知识就算全齐活了。

今天学习的内容同学们学习起来会更轻松一些,有一些语法知识只需要了解一下 就可以了,因为实际工作用得并不多。

  1. 内部类
    1. 成员内部类 🍐
    2. 静态内部类 🍐
    3. 局部内部类 🍐
    4. 匿名内部类 🍐 ❤️
  2. 枚举
    1. 枚举的定义 🍐
    2. 枚举的应用 🍐 ✏️
  3. 泛型
    1. 自定义泛型类 🍐
    2. 自定义泛型接口 🍐
    3. 泛型方法 🍐
    4. 泛型限定 🍐 ❤️
    5. 泛型擦除 🍐
  4. 常用API
    1. Object类 🍐 ❤️
    2. Objects类 ✏️
    3. 基本类型包装类 🍐 ❤️

1. 内部类 🍐

内部类

内部类是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。

当一个类的内部,包含一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。

比如:汽车、的内部有发动机,发动机是包含在汽车内部的一个完整事物,可以把发动机设计成内部类。

public class Car{
	
    public class Engine{
        //内部类
    }
}


 
 
 

内部类有四种形式,分别是成员内部类、静态内部类、局部内部类、匿名内部类。

代码操作

1.1 成员内部类

成员内部类就是类中的一个普通成员,类似于成员变量、成员方法。

public class Outer {
    private int age = 99;
    public static String a="黑马";

    // 成员内部类
    public class Inner{
        private String name;
        private  int age = 88;//内部类成员变量(以后无论静态还是非静态的统称为成员变量)

        //在内部类中既可以访问自己类的成员,也可以访问外部类的成员
        public void test(){
            System.out.println(age); //88
            System.out.println(a);   //黑马

            int age = 77;
            System.out.println(age); //77
            System.out.println(this.age); //88
            System.out.println(Outer.this.age); //99
        }

        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 class Test {
    public static void main(String[] args) {
        //外部类.内部类 变量名 = new 外部类().new 内部类();
        Outer.Inner in = new Outer().new Inner();
        //调用内部类的方法
        in.test();
    }
}




 





image
image

总结一下内部类访问成员的特点: 👇

  • 既可以访问内部类成员、也可以访问外部类成员
  • 如果内部类成员和外部类成员同名,可以使用类名.this.成员区分

总结

课堂作业

  1. 什么是内部类? 什么情况可以使用内部类,举个例子?🎤
  2. 练习的话,速写前3中,最后的匿名内部类多写一遍!
  3. 下列ABCD哪个是匿名内部类? E处这样写有什么好处?匿名内部类会不会生成class文件? image

二、枚举

认识枚举和应用枚举

2.1 认识枚举、枚举的原理

同学们,接下来我们学习一个新的知识点,枚举 。枚举是我们以后在项目开发中偶尔会用到的知识。话不多说,我们还是先来认识一下枚举。

枚举是一种特殊的类,它的格式是:✏️

  public enum s {
  	枚举项1,枚举项2,枚举项3;
  }

  注意:
  1. 定义枚举类要用关键字enum
  2. 枚举项之间用,隔开
  3. 枚举项的最后一个建议使用;结尾
  4. 枚举项一般大写
  5. 枚举是一种特殊的类

其实枚举项就表示枚举类的对象,只是这些对象在定义枚举类时就预先写好了,以后就只能用这几个固定的对象。 👇 👇

我们用代码演示一下,定义一个枚举类A,在枚举类中定义三个枚举项X, Y, Z

public enum A{
   X,Y,Z;
}

想要获取枚举类中的枚举项,只需要用类名调用就可以了

public class Test{
   public static void main(String[] args){
       //获取枚举A类的,枚举项
       A a1 = A.X;
       A a2 = A.Y;
       A a3 = A.Z;
   }
}

刚才说,枚举项实际上是枚举类的对象,这一点其实可以通过反编译(javap指令 )的形式来验证(需要用到反编译的命令,这里不能直接将字节码拖进idea反编译) image

我们会看到,枚举类A是用class定义的,说明枚举确实是一个类,而且X,Y,Z都是A类的对象;而且每一个枚举项都是被public static final 修饰,所以被可以类名调用,而且不能更改。

总结

  • 格式
  public enum s {
  	枚举项1,枚举项2,枚举项3;
  }
  注意:
  1. 定义枚举类要用关键字enum
  2. 枚举项之间用,隔开
  3. 枚举项的最后一个建议使用;结尾
  4. 枚举项一般大写

应用场景:枚举一般表示几个固定的值,然后作为参数进行传输。

课堂作业

  1. 枚举本质是什么? 可以通过什么命令进行反编译得到证据!!🎤

  2. 在实际开发中,枚举的方法,有参构造,成员变量应用多吗?🎤

  3. 根据下列需求,完成枚举类的定义 ✏️

练习1:定义一个枚举类,用来表示春,夏,秋,冬这四个固定值
提示:
 - 枚举类名:Season
 - 春
 - 夏
 - 秋
 - 冬

3-6 春  7-9 夏  9-11 秋   12-2冬天
结合Scanner 输入对应的月份和枚举类,打印对应的季节

 > 英语单词可以使用翻译插件

练习2:完成星期一到星期天的枚举定义
提示:
- 枚举类名:Week
- 星期一:MON
- 星期二:TUE
- 星期三:WEB
- 星期四:THU
- 星期五:FRI
- 星期六:SAT
- 星期天:SUN

三、泛型

泛型

3.1 认识泛型

泛型指的是,在定义类、接口、方法 时,同时声明了一个或者多个类型变量(如:<E>),称为泛型类、泛型接口、泛型方法、它们统称为泛型。

比如我们前面学过的ArrayList类就是一个泛型类,我们可以打开API文档看一下ArrayList类的声明。

1665671616852
1665671616852

ArrayList集合的设计者在定义ArrayList集合时,就已经明确ArrayList集合时给别人装数据用的,但是别人用ArrayList集合时候,装什么类型的数据他不知道,所以就用一个<E>表示元素的数据类型。

当别人使用ArrayList集合创建对象时,new ArrayList<String> 就表示元素为String类型,new ArrayList<Integer>表示元素为Integer类型。

1665671987771
1665671987771

我们总结一下泛型的作用、本质: 👇 👇

  • 泛型的好处:在编译阶段可以避免出现一些非法的数据。

  • 泛型的本质:把具体的数据类型传递给类型变量。

代码操作

3.2 自定义泛型类

接下来我们学习一下自定义泛型类,但是有一些话需要给大家提前交代一下:泛型类 ,在实际工作中一般都是源代码中写好,我们直接用的,就是ArrayList<E>这样的,自己定义泛型类是非常少的。

image
image

自定义泛型类的格式如下

//这里的<T,W>其实指的就是类型变量,可以是一个,也可以是多个。
public class 类名<T,W>{
    
}

接下来,我们自己定义一个MyArrayList<E>泛型类,模拟一下自定义泛型类的使用。

注意: 这里重点仅仅只是模拟泛型类的使用,所以方法中的一些逻辑是次要的,也不会写得太严谨。

//1.定义一个泛型类,用来表示一个容器
//2.容器中存储的数据,它的类型用<E>先代替用着,等调用者来确认<E>的具体类型。
public class MyArrayList<E>{
    private Object[] array = new Object[10];
    //3.定一个索引,方便对数组进行操作
    private int index;
    
    //4.添加元素
    public void add(E e){
        array[index]=e;
        index++;
    }
    
    //5.获取元素
    public E get(int index){
        return (E)array[index];
    }
}

接下来,我们写一个测试类,来测试自定义的泛型类MyArrayList是否能够正常使用

public class Test{
    public static void main(String[] args){
        //1.确定MyArrayList集合中,元素类型为String类型
        MyArrayList<String> list = new MyArrayList<>();
        //此时添加元素时,只能添加String类型
        list.add("张三");
        list.add("李四");
        
         //2.确定MyArrayList集合中,元素类型为Integer类型
        MyArrayList<Integer> list1 = new MyArrayList<>();
        //此时添加元素时,只能添加String类型
        list.add(100);
        list.add(200);
        
    }
}

结合上述案例,再次回味泛型的本质:把具体的数据类型传递给类型变量。

关于自定义泛型类,你们把这个案例理解,对于初学者来说,就已经非常好了👍

速度练一下,感受下!!本质

总结

课堂作业

  1. 泛型的好处是什么?泛型的本质是什么?.class文件中有泛型吗?
  2. 看图解释说明问题 image

四、常用API

常用API

各位同学,恭喜大家,到目前位置我们关于面向对象的语法知识就全部学习完了。接下来我们就可以拿着这些语法知识,去学习一个一个的API方法,掌握的API方法越多,那么Java的编程能力就越强。

常用API

API(Application Programming interface)意思是应用程序编程接口,说人话就是Java帮我们写好的一些程序,如:类、方法等,我们直接拿过来用就可以解决一些问题。

1665752705389
1665752705389

我们要学习那些API呢?把下面一种图中的所有类的常用方法学会了,那我们JavaSE进阶的课程就算你全学会了。

1665752813753
1665752813753

很多初学者给我反应的问题是:👇

1665752883617
1665752883617

4.1 Object类 🍐 🚀

Object类

各位小伙伴,我们要学习的第一个API就是Object类 。Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用Object类中提供的一些方法。

在线JDK文档:https://www.runoob.com/manual/jdk11api/index.htmlopen in new window

按照下图的提示,可以搜索到你想要找的类

image
image

我们找到Object类的下面两个方法

image
image

代码操作

  • 4.1.1 toString()方法

我们先来学习toString()方法。

public String toString()
    调用toString()方法可以返回对象的字符串表示形式。
    默认的格式是:“包名.类名@哈希值16进制”

假设有一个学生类如下

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

再定义一个测试类

public class Test{
    public static void main(String[] args){
        Student s1 = new Student("赵敏",23);
        System.out.println(s1.toString()); 
    }
}

打印结果如下

1665753662732
1665753662732

如果,在Student类重写toString()方法,那么我们可以返回对象的属性值,代码如下

public class Student{
    private String name;
    private int age;
    
    public Student(String name, int age){
        this.name=name;
        this.age=age;
    }
    
    @Override
    public String toString(){
        return "Student{name=‘"+name+"’, age="+age+"}";
    }
}

运行测试类,结果如下

1665754067446
1665754067446

练习一下👉

总结

课堂作业

  1. toString方法在开发中有何意义?
  2. 结合下面的图片 浅克隆和深拷贝有什么区别?🎤 image

4.2 Objects类 了解一下 🍐 🚀

Objects类

Objects是一个工具类,提供了一些方法可以对任意对象进行操作。主要方法如下

1665760840329
1665760840329

下面写代码演示一下这几个方法

public class Test{
    public static void main(String[] args){
        String s1 = null;
        String s2 = "itheima";
        
        //这里会出现NullPointerException异常,调用者不能为null
        System.out.println(s1.equals(s2));
        //此时不会有NullPointerException异常,底层会自动先判断空
        System.out.println(Objects.equals(s1,s2));
        
        //判断对象是否为null,等价于==
        System.out.println(Objects.isNull(s1)); //true
        System.out.println(s1==null); //true
        
        //判断对象是否不为null,等价于!=
        System.out.println(Objects.nonNull(s2)); //true
        System.out.println(s2!=null); //true
    }
}

4.3 基本类型包装类 🍐 ✏️❤️

基本类型包装类

同学们,接下来我们学习一下包装类 。为什么要学习包装类呢?因为在Java中有一句很经典的话,万物皆对象。 Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。

Java中8种基本数据类型都用一个包装类与之对一个,如下图所示

1665758797003
1665758797003

我们学习包装类,主要学习两点:

    1. 创建包装类的对象方式、自动装箱和拆箱的特性;
    1. 利用包装类提供的方法对字符串和基本类型数据进行相互转换

代码操作

4.2.1 创建包装类对象

我们先来学习,创建包装类对象的方法,以及包装类的一个特性叫自动装箱和自动拆箱。我们以Integer为例,其他的可以自己学,都是类似的。

//1.创建Integer对象,封装基本类型数据10
Integer a = new Integer(10);

//2.使用Integer类的静态方法valueOf(数据)
Integer b = Integer.valueOf(10);

//3.还有一种自动装箱的写法(意思就是自动将基本类型转换为引用类型)
Integer c = 10;

//4.有装箱肯定还有拆箱(意思就是自动将引用类型转换为基本类型)
int d = c;

//5.装箱和拆箱在使用集合时就有体现
ArrayList<Integer> list = new ArrayList<>();
//添加的元素是基本类型,实际上会自动装箱为Integer类型
list.add(100);
//获取元素时,会将Integer类型自动拆箱为int类型
int e = list.get(0);

总结

课堂作业

  1. 为什么要有包装类?举个例子?🎤

结合字符串转数字

课后作业

🚩 1. 重点完成上述的课堂作业

  1. 晚自习第一节课的前30分钟,总结完毕之后,每个同学先必须梳理今日知识点 (记得写不知道的,以及感恩三件事);整理好的笔记可以发给组长,组长交给班长,意在培养大家总结的能力)

  2. 晚自习第一节课的后30分钟开始练习(记住:程序员是代码堆起来的):

    • 先要把今天的所有案例或者课堂练习,如果没练完的,练完他
    • 完成讲师发送在班级群中的作业,提交位置关注群里
    • 不懂要多问,问同学,问老师,问百度,都可以!! 独自解决分析问题,解决问题的能力-----编程思维!!
  3. 剩余的时间:预习第二天的知识,预习的时候一定要注意:

  • 预习不是学习,不要死看第二天的视频(很容易出现看了白看,为了看视频而看视频)
  • 预习看第二天的笔记,把笔记中标注重要的知识,可以找到预习视频,先看一遍,如果不懂的 ,记住做好标注。