Java面向对象

Java面向对象

静态 static

static修饰静态成员变量

/**
      在线人数。
      注意:static修饰的成员变量:静态成员变量,只在内存中有一份,可以被共享
     */
public static int onlineNumber = 161;

Java面向对象_第1张图片

static静态成员方法

/**
   静态成员方法: 有static修饰,归属于类,可以被共享访问,用类名或者对象名都可以访问。
 */
public static int getMax(int age1, int age2){
    return age1 > age2 ? age1 : age2;
}

Java面向对象_第2张图片
Java面向对象_第3张图片
Java面向对象_第4张图片

单例模式

Java面向对象_第5张图片

饿汉单例设计模式

Java面向对象_第6张图片

/**
   使用饿汉单例实现单例类
 */
public class SingleInstance {

    /**
      2、饿汉单例是在获取对象前,对象已经提前准备好了一个。
       这个对象只能是一个,所以定义静态成员变量记住。
     */
    public static SingleInstance instance = new SingleInstance();

    /**
       1、必须把构造器私有化。
     */
    private SingleInstance(){
    }
}

懒汉单例设计模式

Java面向对象_第7张图片

/**
   懒汉单例
 */
public class SingleInstance2 {

    /**
      2、定义一个静态的成员变量负责存储一个对象。
         只加载一次,只有一份。
       注意:最好私有化,这样可以避免给别人挖坑!
     */
    private static SingleInstance2 instance;

    /**
      3、提供一个方法,对外返回单例对象。
     */
    public static SingleInstance2 getInstance() {
        if(instance == null){
            // 第一次来拿对象 :此时需要创建对象。
            instance = new SingleInstance2();
        }
        return instance;
    }


    /**
       1、私有化构造器
     */
    private SingleInstance2(){
    }
}

final

目标:记住final的语法。

  • 1、final修饰类,类不能被继承。
class Wolf extends Animal{
}

final class Animal{
}
  • 2、final修饰方法,方法不能被重写
public final void eat(){
    System.out.println("人都要吃东西~~");
}
  • 3、final修饰变量,总规则:变量有且仅能被赋值一次。
private final String name = "猪刚鬣";

Java面向对象_第8张图片

常量 public static final

常量:public static final 修饰的成员变量,注意:名称全部英文大写,多个单词下划线连接。

public static final String schoolName = "黑马";

Java面向对象_第9张图片

枚举 enum

public enum Season {
    // 第一行罗列枚举的实例:对象的名称。
    SPRING,SUMMER,AUTUMN, WINTER;
}
public static void move(Constant orientation){
    // 控制玛丽移动
    switch (orientation) {
        case UP:
            System.out.println("玛丽往↑飞了一下~~");
            break;
        case DOWN:
            System.out.println("玛丽往↓蹲了一下~~");
            break;
        case LEFT:
            System.out.println("玛丽往←跑了一下~~");
            break;
        case RIGHT:
            System.out.println("玛丽往→跑了一下~~");
            break;
    }
}

Java面向对象_第10张图片

抽象 abstract

/**
  抽象类:有abstract修饰
 */
public abstract class Animal {
    private String name;
    /**
       抽象方法:有abstract修饰 不能写方法体代码
     */
    public abstract void run();

    public String getName() {
        return name;
    }

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

Java面向对象_第11张图片
Java面向对象_第12张图片

模板方法模式

Java面向对象_第13张图片

模板方法模式 写作文案例案例

  • 父类声明模板方法,并提供子类重写的抽象类
/**
 * @author
 * @create 2022-06-21 13:47
 */
public abstract class Student {

    /**
     * 正式声明了模板方法模式
     *
     */
    public final void write(){
        // 标题
        System.out.println("\t\t\t\t《我的爸爸》");
        // 开头
        System.out.println("你的爸爸是啥样,来说说:");
        // 正文部分(每个子类都要写的,每个子类写的情况不一样
        //  因此。模板方法把正文部分定义成抽象方法,交给
        //  具体的子类来完成)

        System.out.println(writeMain());

        // 结尾
        System.out.println("我的爸爸简直太好了~~");
    }

    public abstract String writeMain();
}
  • 子类继承父类,重写父类的抽象类
/**
 * @author 小学生
 * @create 2022-06-21 13:46
 */
public class StudentChild extends Student{

    @Override
    public String writeMain() {
        return "的爸爸太牛b了,他总是买东西给我吃。。";
    }

}
  • 最终实现
/**
 * @author
 * @create 2022-06-21 13:50
 */
public class Test {

    public static void main(String[] args) {
        // 目标:理解模板方法模式的思想和使用步骤。
        StudentChild studentChild = new StudentChild();
        studentChild.write();
    }
}

Java面向对象_第14张图片

接口 interface

Java面向对象_第15张图片

  • 接口体现了一种规范,规范一定是公开的

Java面向对象_第16张图片
Java面向对象_第17张图片

接口的新增方法

Java面向对象_第18张图片
Java面向对象_第19张图片
Java面向对象_第20张图片
Java面向对象_第21张图片

  • 接口
public interface SportMan {

    /**
       1、默认方法:其实就是实例方法。
           -- 必须用default修饰,默认会自带public
           -- 必须用接口的实现类的对象来调用
     */
    default void run(){
        go();
        System.out.println("==跑的贼溜==");
    }

    /**
      2、静态方法
            -- 必须static修饰,默认会自带public
            -- 必须用接口名自己调用
     */
    static void inAddr(){
        System.out.println("我们在黑马");
    }

    /**
      3、私有实例方法:
           -- 必须用private修饰
           -- 只能本接口中访问。
           -- 一般给接口中其他的默认方法或者私有实例方法使用的
     */
//    private void go(){
//        System.out.println("开始跑~~");
//    }

    static void go(){
        System.out.println("开始跑~~");
    }
}
  • 实现接口但是不用实现方法
public class PingPongMan implements SportMan{
}
  • 测试:
public class Test {
    public static void main(String[] args) {
        // 目标:理解JDK 8开始接口新增的方法。
        PingPongMan p = new PingPongMan();
        p.run();

        SportMan.inAddr();


    }
}

Java面向对象_第22张图片
Java面向对象_第23张图片

多态

多态概述和好处

Java面向对象_第24张图片
Java面向对象_第25张图片

  • 创建父类动物对象
/**
    父类
 */
public class Animal {
    public String name = "动物名称";
    public void run(){
        System.out.println("动物可以跑~~");
    }
}
  • 创建子类狗对象 继承父类对象
public class Dog extends Animal{
    public String name = "狗名称";
    @Override
    public void run() {
        System.out.println("跑的贼溜~~~~~");
    }
}
  • 测试
public class Test {
    public static void main(String[] args) {
        // 目标:先认识多态的形式
        // 父类  对象名称 = new 子类构造器();
        Animal a = new Dog();
        a.run(); // 方法调用:编译看左,运行看右
        System.out.println(a.name); // 方法调用:编译看左,运行也看左,动物名称

    }
}

多态下引用数据类型的类型装换

Java面向对象_第26张图片
Java面向对象_第27张图片

/**
     目标:学习多态形式下的类中转换机制。
 */
public class Test {
    public static void main(String[] args) {
        // 自动类型转换
        Animal a = new Dog();
        a.run();
//        a.lookDoor(); // 多态下无法调用子类独有功能

        // 强制类型转换:可以实现调用子类独有功能的
        Dog d = (Dog) a;
        d.lookDoor();

        // 注意:多态下直接强制类型转换,可能出现类型转换异常
        // 规定:有继承或者实现关系的2个类型就可以强制类型转换,运行时可能出现问题。
        // Tortoise t1 = (Tortoise) a;
        // 建议强制转换前,先判断变量指向对象的真实类型,再强制类型转换。

        if(a instanceof Tortoise){
            Tortoise t = (Tortoise) a;
            t.layEggs();
        }else if(a instanceof Dog){
            Dog d1 = (Dog) a;
            d1.lookDoor();
        }

        System.out.println("---------------------");
        Animal a1 = new Dog();
        go(a1);
    }

    public static void go(Animal a){
        System.out.println("预备~~~");
        a.run();
        // 独有功能
        if(a instanceof Tortoise){
            Tortoise t = (Tortoise) a;
            t.layEggs();
        }else if(a instanceof Dog){
            Dog d1 = (Dog) a;
            d1.lookDoor();
        }
        System.out.println("结束~~~~");
    }
}

Java面向对象_第28张图片

内部类

Java面向对象_第29张图片

静态内部类

Java面向对象_第30张图片

  • 创建静态内部类
/**
   外部类
 */
public class Outer {

    public static int a = 100;
    private String hobby;

    /**
       学习静态成员内部类
     */
    public static class Inner{
        private String name;
        private int age;
        public static String schoolName;

        public Inner(){}

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

        public void show(){
            System.out.println("名称:" + name);
            System.out.println(a);
            // System.out.println(hobby); // 报错!
//            Outer o = new Outer();
//            System.out.println(o.hobby);
        }

        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) {
        Outer.Inner in = new Outer.Inner();
        in.setName("张三");
        in.show();
    }
}

Java面向对象_第31张图片
Java面向对象_第32张图片

成员内部类

Java面向对象_第33张图片

  • 创建成员内部类
/**
   外部类
 */
public class Outer {
    public static int num = 111;
    private String hobby;

    public Outer() {
    }

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

    /**
       成员内部类:不能加static修饰 属于外部类对象的
     */
    public class Inner{
        private String name;
        private int age;
//        public static int a = 100; // JDK 16开始支持静态成员了
//
//        public static void test(){
//            System.out.println(a);
//        }

        public void show(){
            System.out.println("名称:" + name);
            System.out.println("数量:" + num);
            System.out.println("爱好:" + hobby);
        }

        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) {
        Outer.Inner in = new Outer().new Inner();
        in.setName("内部");
        in.show();
//        Outer.Inner.test();

        System.out.println("------------");
        Outer.Inner in1 = new Outer("爱听课").new Inner();
        in1.show();
    }
}

Java面向对象_第34张图片
Java面向对象_第35张图片
Java面向对象_第36张图片

  • 案例
public class Test2 {
    public static void main(String[] args) {
        People.Heart heart = new People().new Heart();
        heart.show();
    }
}

class People{
    private int heartbeat = 150;

    /**
       成员内部类
     */
    public class Heart{
        private int heartbeat = 110;

        public void show(){
            int heartbeat = 78;
            System.out.println(heartbeat); // 78
            System.out.println(this.heartbeat); // 110
            System.out.println(People.this.heartbeat); // 150
        }
    }
}

局部内部类

Java面向对象_第37张图片

匿名内部类

Java面向对象_第38张图片
Java面向对象_第39张图片

  • 匿名内部类案例
/**
      目标:学习匿名内部类的形式和特点。
 */
public class Test {
    public static void main(String[] args) {
        Animal a = new Animal(){
            @Override
            public void run() {
                System.out.println("老虎跑的块~~~");
            }
        };
        a.run();
    }
}

abstract class Animal{
    public abstract void run();
}
  • 匿名内部类的常见使用形式
/**
    目标:掌握匿名内部类的使用形式(语法)
 */
public class Test2 {
    public static void main(String[] args) {
        Swimming s = new Swimming() {
            @Override
            public void swim() {
                System.out.println("学生快乐的自由泳‍");
            }
        };
        go(s);

        System.out.println("--------------");

        Swimming s1 = new Swimming() {
            @Override
            public void swim() {
                System.out.println("老师泳的贼快~~~~~");
            }
        };
        go(s1);

        System.out.println("--------------");

        go(new Swimming() {
            @Override
            public void swim() {
                System.out.println("运动员的贼快啊~~~~~");
            }
        });


    }

    /**
       学生 老师 运动员可以一起参加游泳比赛
     */
    public static void go(Swimming s){
        System.out.println("开始。。。");
        s.swim();
        System.out.println("结束。。。");
    }
}


interface Swimming{
    void swim();
}

重写equals

  • equals默认是比较2个对象的地址是否相同,子类重写后会调用子类重写的来比较内容是否相同。
public class Student { //extends Object{
    private String name;
    private char sex;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    /**
     定制相等规则。
     两个对象的内容一样就认为是相等的
     s1.equals(s2)
     比较者:s1 == this
     被比较者: s2 ==> o
     */
    @Override
    public boolean equals(Object o) {
        // 1、判断是否是同一个对象比较,如果是返回true。
        if (this == o) return true;
        // 2、如果o是null返回false  如果o不是学生类型返回false  ...Student !=  ..Pig
        if (o == null || this.getClass() != o.getClass()) return false;
        // 3、说明o一定是学生类型而且不为null
        Student student = (Student) o;
        return sex == student.sex && age == student.age && Objects.equals(name, student.name);
    }


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex=" + sex +
                ", age=" + age +
                '}';
    }
}
import java.util.Objects;

/**
    目标:掌握Object类中equals方法的使用。
 */
public class Test2 {
    public static void main(String[] args) {
        Student s1 = new Student("周雄", '男', 19);
        Student s2 = new Student("周雄", '男', 19);
        // equals默认是比较2个对象的地址是否相同,子类重写后会调用子类重写的来比较内容是否相同。
        System.out.println(s1.equals(s2));
        System.out.println(s1 == s2);

        System.out.println(Objects.equals(s1, s2));
    }
}

包装类

Java面向对象_第40张图片
Java面向对象_第41张图片

  • 1、可以赋值为空
Integer age1 = null;
  • 2、可以调用toString()方法得到字符串
Integer i3 = 23;
String rs = i3.toString();
System.out.println(rs + 1);
  • 3、可以把字符串类型的数值转换成真实的数据类型
String number = "23";
//转换成整数
int age = Integer.parseInt(number);
System.out.println(age + 1);
  • 4、扩展直接使用valueOf(),可以转任意类型的数值;
String number = "23";
//转换成整数
int age = Integer.valueOf(number);
System.out.println(age + 1);

Java面向对象_第42张图片

Lambda表达式

Java面向对象_第43张图片


/**
 * @author
 * @create 2022-06-22 9:55
 */
public class LambdaDemo2_My {
    // 目标:学会使用Lambda的标准格式简化匿名内部类的代码形式
    // 注意:Lambda只能简化接口中只有一个抽象方法的匿名内部类形式(函数式接口)

    public static void main(String[] args) {
        
        // 第一种方式
        Pwimming pwimming = new Pwimming() {
            @Override
            public void swim() {
                System.out.println("老师游泳");
            }
        };
        go(pwimming);

        System.out.println("===============");
        
        // 简化
        Pwimming pwimming1 = () ->{
            System.out.println("学生游泳");
        };
        go(pwimming1);

        System.out.println("=================");
        
        // 再简化
        go(() -> {
            System.out.println("运动员游泳");
        });

        // 再简化
        System.out.println("=================");
        go(() -> System.out.println("我游泳"));
    }
    
    
    public static void go(Pwimming pwimming){
        System.out.println("开始。。。");
        
        pwimming.swim();
        
        System.out.println("结束。。。");
    }
    
}

@FunctionalInterface // 一旦加上这个注解必须是函数式接口,里面只能有一个抽象方法
interface Pwimming{
    void swim();
}

Java面向对象_第44张图片
Java面向对象_第45张图片

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Comparator;

public class LambdaDemo3 {
    public static void main(String[] args) {
        Integer[] ages1 = {34, 12, 42, 23};
        /**
         参数一:被排序的数组 必须是引用类型的元素
         参数二:匿名内部类对象,代表了一个比较器对象。
         */
//        Arrays.sort(ages1, new Comparator() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return o2 - o1; //  降序
//            }
//        });

//        Arrays.sort(ages1, (Integer o1, Integer o2) -> {
//                return o2 - o1; //  降序
//        });


//        Arrays.sort(ages1, ( o1,  o2) -> {
//            return o2 - o1; //  降序
//        });

        Arrays.sort(ages1, ( o1,  o2 ) ->  o2 - o1 );

        System.out.println(Arrays.toString(ages1));

        System.out.println("---------------------------");
        JFrame win = new JFrame("登录界面");
        JButton btn = new JButton("我是一个很大的按钮");
//        btn.addActionListener(new ActionListener() {
//            @Override
//            public void actionPerformed(ActionEvent e) {
//                System.out.println("有人点我,点我,点我!!");
//            }
//        });

//        btn.addActionListener((ActionEvent e) -> {
//                System.out.println("有人点我,点我,点我!!");
//        });

//        btn.addActionListener(( e) -> {
//            System.out.println("有人点我,点我,点我!!");
//        });

//        btn.addActionListener( e -> {
//            System.out.println("有人点我,点我,点我!!");
//        });

        btn.addActionListener( e -> System.out.println("有人点我,点我,点我!!") );



        win.add(btn);
        win.setSize(400, 300);
        win.setVisible(true);
    }
}

Stream流

Java面向对象_第46张图片
Java面向对象_第47张图片

  • 获取Stream流方式
public class StreamDemo02 {
    public static void main(String[] args) {
        /** --------------------Collection集合获取流-------------------------------   */
        Collection<String> list = new ArrayList<>();
        Stream<String> s =  list.stream();

        /** --------------------Map集合获取流-------------------------------   */
        Map<String, Integer> maps = new HashMap<>();
        // 键流
        Stream<String> keyStream = maps.keySet().stream();
        // 值流
        Stream<Integer> valueStream = maps.values().stream();
        // 键值对流(拿整体)
        Stream<Map.Entry<String,Integer>> keyAndValueStream =  maps.entrySet().stream();

        /** ---------------------数组获取流------------------------------   */
        String[] names = {"赵敏","小昭","灭绝","周芷若"};
        Stream<String> nameStream = Arrays.stream(names);
        Stream<String> nameStream2 = Stream.of(names);

    }
}

Java面向对象_第48张图片
Java面向对象_第49张图片
Java面向对象_第50张图片

/**
     目标:Stream流的常用API
     forEach : 逐一处理(遍历)
     count:统计个数
     -- long count();
     filter : 过滤元素
     -- Stream filter(Predicate predicate)
     limit : 取前几个元素
     skip : 跳过前几个
     map : 加工方法
     concat : 合并流。
 */
public class StreamDemo03_My {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");

        list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);

        long count = list.stream().filter(s -> s.length() == 3).count();
        System.out.println(count);

        list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(System.out::println);

        list.stream().filter(s -> s.startsWith("张")).skip(2).forEach(System.out::println);

        // map加工方法: 第一个参数原材料  -> 第二个参数是加工后的结果。
        // 给集合元素的前面都加上一个:黑马的:
        list.stream().map(s -> "黑马的:"+s).forEach(System.out::println);

        List<Student> collect = list.stream().map(s -> {
            Student student = new Student(s);
            return student;
        }).collect(Collectors.toList());
        System.out.println(collect);

        // 合并流。
        Stream<String> stream = list.stream().filter(s -> s.startsWith("张"));
        Stream<String> java1 = Stream.of("java1", "java2");
        Stream<String> concat = Stream.concat(stream,java1);
        System.out.println(concat);
    }

}
/**
     目标:收集Stream流的数据到 集合或者数组中去。
 */
public class StreamDemo05 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");

        Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
        List<String> zhangList = s1.collect(Collectors.toList()); // 可变集合
        zhangList.add("java1");
        System.out.println(zhangList);

//       List list1 = s1.toList(); // 得到不可变集合
//       list1.add("java");
//       System.out.println(list1);

        // 注意注意注意:“流只能使用一次”
        Stream<String> s2 = list.stream().filter(s -> s.startsWith("张"));
        Set<String> zhangSet = s2.collect(Collectors.toSet());
        System.out.println(zhangSet);

        Stream<String> s3 = list.stream().filter(s -> s.startsWith("张"));
//         Object[] arrs = s3.toArray();
//        String[] arrs = s3.toArray(s -> new String[s]); // 可以不管,拓展一下思维!!
        String[] arrs1 = s3.toArray(String[]::new); // 可以不管,拓展一下思维!!
        System.out.println("Arrays数组内容:" + Arrays.toString(arrs1));

    }
}

反射

Java面向对象_第51张图片
Java面向对象_第52张图片
Java面向对象_第53张图片

  • 反射的第一步:获取Class对象
/**
   目标:反射的第一步:获取Class对象
 */
public class Test {
    public static void main(String[] args) throws Exception {
        // 1、Class类中的一个静态方法:forName(全限名:包名 + 类名)
        Class c = Class.forName("com.itheima.d2_reflect_class.Student");
        System.out.println(c); // Student.class

        // 2、类名.class
        Class c1 = Student.class;
        System.out.println(c1);

        // 3、对象.getClass() 获取对象对应类的Class对象。
        Student s = new Student();
        Class c2 = s.getClass();
        System.out.println(c2);
    }
}
  • 使用反射获取构造器对象
    Java面向对象_第54张图片
/**
    目标:反射_获取Constructor构造器对象.

    反射的第一步是先得到Class类对象。(Class文件)

    反射中Class类型获取构造器提供了很多的API:
         1. Constructor getConstructor(Class... parameterTypes)
            根据参数匹配获取某个构造器,只能拿public修饰的构造器,几乎不用!
         2. Constructor getDeclaredConstructor(Class... parameterTypes)
            根据参数匹配获取某个构造器,只要申明就可以定位,不关心权限修饰符,建议使用!
         3. Constructor[] getConstructors()
            获取所有的构造器,只能拿public修饰的构造器。几乎不用!!太弱了!
         4. Constructor[] getDeclaredConstructors()
            获取所有申明的构造器,只要你写我就能拿到,无所谓权限。建议使用!!
    小结:
        获取类的全部构造器对象: Constructor[] getDeclaredConstructors()
            -- 获取所有申明的构造器,只要你写我就能拿到,无所谓权限。建议使用!!
        获取类的某个构造器对象:Constructor getDeclaredConstructor(Class... parameterTypes)
            -- 根据参数匹配获取某个构造器,只要申明就可以定位,不关心权限修饰符,建议使用!

 */
public class TestStudent01 {
    // 1. getConstructors:
    // 获取全部的构造器:只能获取public修饰的构造器。
    // Constructor[] getConstructors()
    @Test
    public void getConstructors(){
        // a.第一步:获取类对象
        Class c = Student.class;
        // b.提取类中的全部的构造器对象(这里只能拿public修饰)
        Constructor[] constructors = c.getConstructors();
        // c.遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
    }


    // 2.getDeclaredConstructors():
    // 获取全部的构造器:只要你敢写,这里就能拿到,无所谓权限是否可及。
    @Test
    public void getDeclaredConstructors(){
        // a.第一步:获取类对象
        Class c = Student.class;
        // b.提取类中的全部的构造器对象
        Constructor[] constructors = c.getDeclaredConstructors();
        // c.遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
        }
    }

    // 3.getConstructor(Class... parameterTypes)
    // 获取某个构造器:只能拿public修饰的某个构造器
    @Test
    public void getConstructor() throws Exception {
        // a.第一步:获取类对象
        Class c = Student.class;
        // b.定位单个构造器对象 (按照参数定位无参数构造器 只能拿public修饰的某个构造器)
        Constructor cons = c.getConstructor();
        System.out.println(cons.getName() + "===>" + cons.getParameterCount());
    }


    // 4.getConstructor(Class... parameterTypes)
    // 获取某个构造器:只要你敢写,这里就能拿到,无所谓权限是否可及。
    @Test
    public void getDeclaredConstructor() throws Exception {
        // a.第一步:获取类对象
        Class c = Student.class;
        // b.定位单个构造器对象 (按照参数定位无参数构造器)
        Constructor cons = c.getDeclaredConstructor();
        System.out.println(cons.getName() + "===>" + cons.getParameterCount());

        // c.定位某个有参构造器
        Constructor cons1 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(cons1.getName() + "===>" + cons1.getParameterCount());

    }

}

Java面向对象_第55张图片

/**
    目标: 反射_获取Constructor构造器然后通过这个构造器初始化对象。

    反射获取Class中的构造器对象Constructor作用:
            也是初始化并得到类的一个对象返回。

    Constructor的API:
         1. T newInstance(Object... initargs)
                创建对象,注入构造器需要的数据。
         2. void setAccessible(true)
                修改访问权限,true代表暴力攻破权限,false表示保留不可访问权限(暴力反射)
    小结:
        可以通过定位类的构造器对象。
        如果构造器对象没有访问权限可以通过:void setAccessible(true)打开权限
        构造器可以通过T newInstance(Object... initargs)调用自己,传入参数!
 */
public class TestStudent02 {
    // 1.调用构造器得到一个类的对象返回。
    @Test
    public void getDeclaredConstructor() throws Exception {
        // a.第一步:获取类对象
        Class c = Student.class;
        // b.定位单个构造器对象 (按照参数定位无参数构造器)
        Constructor cons = c.getDeclaredConstructor();
        System.out.println(cons.getName() + "===>" + cons.getParameterCount());

        // 如果遇到了私有的构造器,可以暴力反射
        cons.setAccessible(true); // 权限被打开

        Student s = (Student) cons.newInstance();
        System.out.println(s);

        System.out.println("-------------------");

        // c.定位某个有参构造器
        Constructor cons1 = c.getDeclaredConstructor(String.class, int.class);
        System.out.println(cons1.getName() + "===>" + cons1.getParameterCount());

        Student s1 = (Student) cons1.newInstance("孙悟空", 1000);
        System.out.println(s1);
    }


}

Java面向对象_第56张图片
Java面向对象_第57张图片

/**
    目标:反射获取成员变量: 取值和赋值。

    Field的方法:给成员变量赋值和取值
        void set(Object obj, Object value):给对象注入某个成员变量数据
        Object get(Object obj):获取对象的成员变量的值。
        void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
        Class getType(); 获取属性的类型,返回Class对象。
        String getName(); 获取属性的名称。
 */
public class FieldDemo02 {
    @Test
    public void setField() throws Exception {
        // a.反射第一步,获取类对象
        Class c = Student.class;
        // b.提取某个成员变量
        Field ageF = c.getDeclaredField("age");

        ageF.setAccessible(true); // 暴力打开权限

        // c.赋值
        Student s = new Student();
        ageF.set(s , 18);  // s.setAge(18);
        System.out.println(s);

        // d、取值
        int age = (int) ageF.get(s);
        System.out.println(age);

    }
}

Java面向对象_第58张图片
在这里插入图片描述

/**
    目标:反射——获取Method方法对象

    反射获取类的Method方法对象:
         1、Method getMethod(String name,Class...args);
             根据方法名和参数类型获得对应的方法对象,只能获得public的

         2、Method getDeclaredMethod(String name,Class...args);
             根据方法名和参数类型获得对应的方法对象,包括private的

         3、Method[] getMethods();
             获得类中的所有成员方法对象,返回数组,只能获得public修饰的且包含父类的

         4、Method[] getDeclaredMethods();
            获得类中的所有成员方法对象,返回数组,只获得本类申明的方法。

    Method的方法执行:
        Object invoke(Object obj, Object... args)
          参数一:触发的是哪个对象的方法执行。
          参数二: args:调用方法时传递的实际参数
 */
public class MethodDemo01 {
    /**
     * 1.获得类中的所有成员方法对象
     */
    @Test
    public void getDeclaredMethods(){
        // a.获取类对象
        Class c = Dog.class;
        // b.提取全部方法;包括私有的
        Method[] methods = c.getDeclaredMethods();
        // c.遍历全部方法
        for (Method method : methods) {
            System.out.println(method.getName() +" 返回值类型:" + method.getReturnType() + " 参数个数:" + method.getParameterCount());
        }
    }

    /**
     * 2. 获取某个方法对象
     */
    @Test
    public void getDeclardMethod() throws Exception {
        // a.获取类对象
        Class c = Dog.class;
        // b.提取单个方法对象
        Method m = c.getDeclaredMethod("eat");
        Method m2 = c.getDeclaredMethod("eat", String.class);

        // 暴力打开权限了
        m.setAccessible(true);
        m2.setAccessible(true);

        // c.触发方法的执行
        Dog d = new Dog();
        // 注意:方法如果是没有结果回来的,那么返回的是null.
        Object result = m.invoke(d);
        System.out.println(result);

        Object result2 = m2.invoke(d, "骨头");
        System.out.println(result2);
    }
}

注解

Java面向对象_第59张图片

public @interface Book {
    String value(); // 特殊属性
    double price() ;
    //double price() default 9.9;
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bookk {
    String value();
    double price() default 100;
    String[] author();
}

/**
   目标:学会自定义注解。掌握其定义格式和语法。
 */
@MyBook(name="《精通JavaSE》",authors = {"黑马", "dlei"} , price = 199.5)
//@Book(value = "/delete")
// @Book("/delete")
@Book(value = "/delete", price = 23.5)
//@Book("/delete")
public class AnnotationDemo1 {

    @MyBook(name="《精通JavaSE2》",authors = {"黑马", "dlei"} , price = 199.5)
    private AnnotationDemo1(){

    }

    @MyBook(name="《精通JavaSE1》",authors = {"黑马", "dlei"} , price = 199.5)
    public static void main(String[] args) {
        @MyBook(name="《精通JavaSE2》",authors = {"黑马", "dlei"} , price = 199.5)
        int age = 21;
    }
}

Java面向对象_第60张图片
Java面向对象_第61张图片
Java面向对象_第62张图片

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.FIELD}) // 元注解
@Retention(RetentionPolicy.RUNTIME) // 一直活着,在运行阶段这个注解也不消失
public @interface MyTest {
}
/**
   目标:认识元注解
 */
//@MyTest // 只能注解方法和成员变量
public class AnnotationDemo2 {

    @MyTest
    private String name;

    @MyTest
    public void test(){

    }

    public static void main(String[] args) {

    }
}

Java面向对象_第63张图片
Java面向对象_第64张图片

/**
   目标:完成注解的解析
 */
public class AnnotationDemo3 {
    @Test
    public void parseClass(){
        // a.先得到类对象
        Class c = BookStore.class;
        // b.判断这个类上面是否存在这个注解
        if(c.isAnnotationPresent(Bookk.class)){
            //c.直接获取该注解对象
            Bookk book = (Bookk) c.getDeclaredAnnotation(Bookk.class);
            System.out.println(book.value());
            System.out.println(book.price());
            System.out.println(Arrays.toString(book.author()));
        }
    }

    @Test
    public void parseMethod() throws NoSuchMethodException {
        // a.先得到类对象
        Class c = BookStore.class;

        Method m = c.getDeclaredMethod("test");

        // b.判断这个类上面是否存在这个注解
        if(m.isAnnotationPresent(Bookk.class)){
            //c.直接获取该注解对象
            Bookk book = (Bookk) m.getDeclaredAnnotation(Bookk.class);
            System.out.println(book.value());
            System.out.println(book.price());
            System.out.println(Arrays.toString(book.author()));
        }
    }
}

@Bookk(value = "《情深深雨濛濛》", price = 99.9, author = {"琼瑶", "dlei"})
class BookStore{

    @Bookk(value = "《三少爷的剑》", price = 399.9, author = {"古龙", "熊耀华"})
    public void test(){
    }
}

动态代理

Java面向对象_第65张图片

  • 定义一个需要代理的接口
/**
 * @author
 * @create 2022-06-23 9:24
 */
public interface Skill {
    void jump(); // 唱歌
    void sing(); // 跳舞

}
  • 实现该接口
/**
 * @author
 * @create 2022-06-23 9:25
 */
public class Star implements Skill{

    private String name;

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

    @Override
    public void jump() {
        System.out.println(name+"开始跳舞,条的好看");
    }

    @Override
    public void sing() {
        System.out.println(name+"开始唱歌,喵喵喵");
    }
}
  • 设计一个方法来返回对象的代理对象
/**
 * @author
 * @create 2022-06-23 9:28
 */
public class StarAgentProxy {

    /**
     * 设计一个方法来返回对象的代理对象
     */
    public static Skill getProxy(Star obj){
        // 为杨超越这个对象,生成一个代理对象
        return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                
               // 参数一:代理对象本身。一般不管
                        // 参数二:正在被代理的方法
                        // 参数三:被代理方法,应该传入的参数
                
                System.out.println("收首付款");
                // 真正让杨超越调用的方法对象
                Object invoke = method.invoke(obj, args);
                System.out.println("经纪人,收尾款");
                return invoke;
            }
        });
    }
}
  • 测试动态代理模式
/**
 * @author
 * @create 2022-06-23 9:26
 */
public class Test {

    public static void main(String[] args) {

        // 目标:学习开发一个动态代理的对象,理解动态代理的执行流程
        // 1.创建一个对象,对象的类必须实现接口
        Star s = new Star("杨超越");
        // 为杨超越生成一个代理对象(经纪人)
        Skill proxy = StarAgentProxy.getProxy(s);
        proxy.jump();
        proxy.sing();


    }
}

你可能感兴趣的:(java,单例模式,开发语言)