> 文章列表 > Java面向对象

Java面向对象

Java面向对象

Java面向对象

静态 static

static修饰静态成员变量

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

Java面向对象

static静态成员方法

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

Java面向对象
Java面向对象
Java面向对象

单例模式

Java面向对象

饿汉单例设计模式

Java面向对象

/使用饿汉单例实现单例类*/
public class SingleInstance {/2、饿汉单例是在获取对象前,对象已经提前准备好了一个。这个对象只能是一个,所以定义静态成员变量记住。*/public static SingleInstance instance = new SingleInstance();/1、必须把构造器私有化。*/private SingleInstance(){}
}

懒汉单例设计模式

Java面向对象

/懒汉单例*/
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面向对象

常量 public static final

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

public static final String schoolName = "黑马";

Java面向对象

枚举 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面向对象

抽象 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面向对象
Java面向对象

模板方法模式

Java面向对象

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

  • 父类声明模板方法,并提供子类重写的抽象类
/* @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{@Overridepublic 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面向对象

接口 interface

Java面向对象

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

Java面向对象
Java面向对象

接口的新增方法

Java面向对象
Java面向对象
Java面向对象
Java面向对象

  • 接口
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面向对象
Java面向对象

多态

多态概述和好处

Java面向对象
Java面向对象

  • 创建父类动物对象
/父类*/
public class Animal {public String name = "动物名称";public void run(){System.out.println("动物可以跑~~");}
}
  • 创建子类狗对象 继承父类对象
public class Dog extends Animal{public String name = "狗名称";@Overridepublic 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面向对象
Java面向对象

/目标:学习多态形式下的类中转换机制。*/
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面向对象

内部类

Java面向对象

静态内部类

Java面向对象

  • 创建静态内部类
/外部类*/
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面向对象
Java面向对象

成员内部类

Java面向对象

  • 创建成员内部类
/外部类*/
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面向对象
Java面向对象
Java面向对象

  • 案例
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); // 78System.out.println(this.heartbeat); // 110System.out.println(People.this.heartbeat); // 150}}
}

局部内部类

Java面向对象

匿名内部类

Java面向对象
Java面向对象

  • 匿名内部类案例
/目标:学习匿名内部类的形式和特点。*/
public class Test {public static void main(String[] args) {Animal a = new Animal(){@Overridepublic 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() {@Overridepublic void swim() {System.out.println("学生快乐的自由泳🏊‍");}};go(s);System.out.println("--------------");Swimming s1 = new Swimming() {@Overridepublic void swim() {System.out.println("老师泳🏊的贼快~~~~~");}};go(s1);System.out.println("--------------");go(new Swimming() {@Overridepublic 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*/@Overridepublic boolean equals(Object o) {// 1、判断是否是同一个对象比较,如果是返回true。if (this == o) return true;// 2、如果o是null返回false  如果o不是学生类型返回false  ...Student !=  ..Pigif (o == null || this.getClass() != o.getClass()) return false;// 3、说明o一定是学生类型而且不为nullStudent student = (Student) o;return sex == student.sex && age == student.age && Objects.equals(name, student.name);}@Overridepublic 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面向对象
Java面向对象

  • 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面向对象

Lambda表达式

Java面向对象


/* @author* @create 2022-06-22 9:55*/
public class LambdaDemo2_My {// 目标:学会使用Lambda的标准格式简化匿名内部类的代码形式// 注意:Lambda只能简化接口中只有一个抽象方法的匿名内部类形式(函数式接口)public static void main(String[] args) {// 第一种方式Pwimming pwimming = new Pwimming() {@Overridepublic 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面向对象
Java面向对象

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<Integer>() {
//            @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面向对象
Java面向对象

  • 获取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面向对象
Java面向对象
Java面向对象

/目标:Stream流的常用APIforEach : 逐一处理(遍历)count:统计个数-- long count();filter : 过滤元素-- Stream<T> filter(Predicate<? super T> 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<String> 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面向对象
Java面向对象
Java面向对象

  • 反射的第一步:获取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、类名.classClass c1 = Student.class;System.out.println(c1);// 3、对象.getClass() 获取对象对应类的Class对象。Student s = new Student();Class c2 = s.getClass();System.out.println(c2);}
}
  • 使用反射获取构造器对象
    Java面向对象
/目标:反射_获取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()@Testpublic 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():// 获取全部的构造器:只要你敢写,这里就能拿到,无所谓权限是否可及。@Testpublic 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修饰的某个构造器@Testpublic 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)// 获取某个构造器:只要你敢写,这里就能拿到,无所谓权限是否可及。@Testpublic 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面向对象

/目标: 反射_获取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.调用构造器得到一个类的对象返回。@Testpublic 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面向对象
Java面向对象

/目标:反射获取成员变量: 取值和赋值。Field的方法:给成员变量赋值和取值void set(Object obj, Object value):给对象注入某个成员变量数据Object get(Object obj):获取对象的成员变量的值。void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。Class getType(); 获取属性的类型,返回Class对象。String getName(); 获取属性的名称。*/
public class FieldDemo02 {@Testpublic 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面向对象
Java面向对象

/目标:反射——获取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.获得类中的所有成员方法对象*/@Testpublic 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. 获取某个方法对象*/@Testpublic 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面向对象

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面向对象
Java面向对象
Java面向对象

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 {@MyTestprivate String name;@MyTestpublic void test(){}public static void main(String[] args) {}
}

Java面向对象
Java面向对象

/目标:完成注解的解析*/
public class AnnotationDemo3 {@Testpublic 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()));}}@Testpublic 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面向对象

  • 定义一个需要代理的接口
/* @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;}@Overridepublic void jump() {System.out.println(name+"开始跳舞,条的好看");}@Overridepublic 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() {@Overridepublic 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();}
}