JAVA—面向对象编程高级
学习了一定基础后,开始更加深入的学习面向对象,包含static,final两个关键字,面向对象编程三大特征之继承和多态。以及对于抽象类,内部类,接口,枚举,泛型的学习。
目录
1.static
(1)修饰成员变量
(2) 修饰成员变量的应用场景
(3)修饰成员方法
(4)修饰成员方法的应用场景
(5)注意事项
(6)应用知识
代码块
单例设计模式
2.继承
(1)介绍与入门
(2)注意事项
[1] 权限修饰符
[2] 单继承,Object类
[3] 方法重写
[4]子类访问其他成员的特点
[5] 子类构造器的特点
3.多态
(1)认识与入门
(2)使用好处
(3)多态下的类型转换问题
4.final
(1)认识与了解
(2)常量详解
5.抽象类
(1)认识与入门
(2)使用好处
(3)应用场景
6.接口
(1)概述
(2)综合案例
(3)接口的细节
7.内部类
(1)内部类概述
(2)成员内部类
(3)静态内部类
(4)局部内部类
(5)匿名内部类*
8.枚举
(1)介绍
(2)应用场景
9.泛型
(1)认识泛型
(2)泛型类
(3)泛型接口
(4)泛型方法,泛型通配符,上下限
(5)注意事项
1.static
静态,修饰成员变量,成员方法。
(1)修饰成员变量
成员变量按照有无static修饰,分为两种:
- 类变量:有static修饰,属于类,在计算机里只有一份,会被类的全部对象共享
- 实例变量(对象的变量):无static修饰,属于每个对象
package W.KN.d1_static;public class Student {//类变量static String name;//实例变量int age;
}
package W.KN.d1_static;public class Text {public static void main(String[] args) {//目标:掌握有无static修饰成员变量的用法,特点//1.类变量的用法//类名.类变量(推荐)Student.name = "郑大风";//对象.类变量(不推荐)Student s1 = new Student();s1.name = "陈清流";Student s2 = new Student();System.out.println(s1.name);System.out.println(Student.name);//实例变量的用法:属于每个对象s1.age = 45;s2.age = 123;System.out.println(s1.age);System.out.println(s2.age);}
}
成员变量执行原理:
类变量,与类一起加载一次,在堆内存中开辟一份空间(且只有一份),后续不论通过类或者对象访问修改的都是同一块空间。实例变量随对象的创建而创建,访问时还是通过对象的地址
(2) 修饰成员变量的应用场景
在开发中,如果某个数据只需要一份,且希望能够被共享(访问,修改),则该数据可以被定义为类变量使用。
案例
系统启动后,要求用户类可以记住自己创建了多少个用户对象
package W.KN.d1_static;public class User {//类变量:对外公开public static int number;public User(){//User.number++;//注意:在同一类中,访问自己类的类变量,可以省略类名不写number++;}}
package W.KN.d1_static;public class Text2 {public static void main(String[] args) {//目标:案例理解类变量的应用场景User u1 = new User();User u2 = new User();User u3 = new User();User u4 = new User();System.out.println(User.number);}
}
(3)修饰成员方法
成员方法按照有无static修饰,分为两种:
- 类方法:有static修饰,属于类(类和对象都可以访问)
- 实例方法:无static修饰,属于对象(只有对象可以访问)
package W.KN.d1_static;public class Student {public static void print(){System.out.println("HelloWorld");}//实例方法public void printfPass(double score){System.out.println("成绩"+(score >= 60 ? "及格":"不及格"));}}
package W.KN.d1_static;public class Text3 {public static void main(String[] args) {//目标:掌握有无static修饰方法的用法//类方法的用法//类名调用Student.print();Student s = new Student();s.print();s.printfPass(100);}
}
成员方法执行原理:
对象之所以可以调用类方法,是由于每个对象都会在堆内存中存储一份类的地址,可以通过地址去调用这些方法,至于类为什么不能调用成员方法,很简单,一是类中没有这些方法的地址,他们都在对象的空间中,二是一般这些方法都有涉及参数,类是无法访问的。
补充: main方法
(4)修饰成员方法的应用场景
类方法最常用的应用场景是做工具类(完成一些功能,给开发人员共同使用)
优点是调用方便,提高效率。工具类没有创建对象的需求,建议将工具类的构造器私有
案例:
对于实现验证码功能出现了重复,为避免浪费空间,在工具类中定义一个类方法实现
package W.KN.d1_static;import java.util.Random;public class MyUtil {public static String creatCoe(int n){//2.定义两个变量,一个用来存储最终产生的随机验证码 一个用来记住可能用到的全部字符String code = "";String data = "abccdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";Random r = new Random();//3.定义一个循环 产生每位随机字符for (int i = 0; i < n; i++) {int index = r.nextInt(data.length());code += data.charAt(index);}return code;}
}
(5)注意事项
- 类方法中可以直接访问类的成员,不可以直接访问实例对象
- 实例方法中既可以直接访问类成员,也可以直接访问实例成员
- 实例方法中可以出现this关键字,类方法中不可以出现this关键字
(6)应用知识
代码块
代码块是类的5大成分之一(成员变量,构造器,方法,代码块,内部块)
分类
静态代码块——格式:static{ }
特点:类加载时自动执行,类只加载一次,所以静态代码只执行一次
作用:完成类的初始化,比如对类的初始化赋值(成员复杂操作赋值)
实例代码块——格式:{ }
特点:每次创建对象时,执行实例代码块,并在构造器前执行
作用:同构造器,是用来完成对象的初始化的(实例变量进行初始化赋值)
package d3_tatic;public class Student {static int number = 80;static String name;//静态代码块static {System.out.println("静态代码块执行了...");name = "楠楠";}//实例代码块//用来执行一些构造器中的重复语句{System.out.println("实例代码块执行了。。。");}public Student(){System.out.println("无参数构造器执行了。。。");}public Student(String name){System.out.println("有参数构造器执行了。。。");}
}
package d3_tatic;public class Text {public static void main(String[] args) {//目标:认识两种代码块,了解他们的特点和基本作用System.out.println(Student.number);System.out.println(Student.number);System.out.println(Student.name);Student s1 =new Student();Student s2 =new Student("楠楠");}
}
单例设计模式
设计模式(Design pattern)
一种问题有n种解法,最优的解法被人总结出来,称之为设计模式
单例设计模式: 确保一个类只有一个对象 避免浪费内存
写法:
- 把类的构造器私有
- 定义一个类变量记住类的一个对象
- 定义一个类方法,返回对象
应用场景:
参照 Runtime 的写法 (返回当前编译环境)
实现方式:
- 饿汉式单例:拿对象时,对象早就创建好了
- 懒汉式单例:拿对象时,才开始创建对象
- .......
2.继承
(1)介绍与入门
java提供了一个关键字extends,使用可以让一个类和另一个类建立起父子关系。
继承的特点:子类能继承父类的非私有成员(成员变量,成员方法)
继承后的创建:子类的对象是由子类和父类共同完成的
package d5_extends;
//父类
public class A {public int i;public void print1(){System.out.println("==print1==");}private int j;private void print2(){System.out.println("==print2");}
}
package d5_extends;
//子类
public class B extends A{public void printf3(){System.out.println("==print3==");System.out.println(i);//子类可以世界使用父类公开的成员print1();//print2(); 父类私有的不可继承}
}
package d5_extends;public class Text {public static void main(String[] args) {//目标:认识继承,掌握继承的特点B b = new B();System.out.println(b.i);b.print1();b.printf3();}
}
继承的执行原理:
子类在方法区中读取时,会将自己的父类也读取一次。对于这个对象就是按照两个模式去创建的
继承的好处:
减少重复代码的编写
package d6_extends;public class People {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;} }package d6_extends;public class Teacher extends People{private String skill;public String getSkill() {return skill;}public void setSkill(String skill) {this.skill = skill;} } package d6_extends;public class Text {public static void main(String[] args) {//目标:清楚继承的好处Teacher t = new Teacher();t.setName("楠楠");t.setSkill("java");System.out.println(t);} }
(2)注意事项
[1] 权限修饰符
权限修饰符就是用来限制类中的成员(成员变量,成员方法,构造器,代码块...)能够访问的范围。
修饰符 | 在本类中 | 同一个包下的其他类里 | 任意包下的子类里 | 任意包的任意类里 |
private | √ | |||
省缺 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
private < 省缺 < protected < public
package d9_modifer;public class Fu {private void privateMethod(){System.out.println("private");}void Method(){System.out.println("省缺");}protected void protectedMethod(){System.out.println("protected");}public void publicMethod(){System.out.println("public");}public void text(){privateMethod();Method();protectedMethod();publicMethod();}
}
[2] 单继承,Object类
java是单继承的,类不支持多继承,但是支持多层继承,java中所有类都是继承于Object类。
[3] 方法重写
当子类觉得父类中某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称,参数列表一致的方法去覆盖父类的方法。重写后,java遵循就近原则访问方法。 (重写后,还想访问父类的方法或者变量,使用super.方法指定访问)
package d7_feature;public class A {public void print(){System.out.println("111");}public void printf(int a,int b){System.out.println("11122112");}
}package d7_feature;public class B extends A {//方法重写public void print(){System.out.println("222");}public void printf(int a,int b){System.out.println("22221313");}
}package d7_feature;public class Text {public static void main(String[] args) {B b = new B();b.print();b.printf(1,2);}
}
注意事项:
- 重写小技巧:使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性会更好。(@Overrride)
- 子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限(public>protected>省缺)
- 重写的方法返回值类型,必须于被重写的方法返回类型一致,或者范围更小。
- 私有方法,静态方法不能被重写,如果重写会报错。
[4]子类访问其他成员的特点
子类方法中访问其他成员(成员变量,成员方法),是依照就近原则的。
[5] 子类构造器的特点
子类的全部构造器,都会先调用父类的构造器,再执行自己
package d10_constructor;class F{public F(){System.out.println("父类F的 无参数构造器 执行了");}
}class Z extends F{public Z(){super();//默认存在的System.out.println("子类Z的 无参数构造器 执行了");}public Z(String name){System.out.println("子类Z的 有参数构造器 执行了");}
}public class Text {public static void main(String[] args) {//目标:先认识子类构造器的特点,再掌握这个特点的常见应用场景Z z = new Z();Z z1 = new Z("楠楠");}
}
this(...)调用兄弟构造器(this() 和super()必须在构造器第一行)
package d10_constructor;class Student{private String name;private int age;private String school;public Student(String name,int age){this(name,age,"中北大学");}public Student() {}public Student(String name, int age, String school) {this.name = name;this.age = age;this.school = school;}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 String getSchool() {return school;}public void setSchool(String school) {this.school = school;}
}public class Text {public static void main(String[] args) {//目标:先认识子类构造器的特点,再掌握这个特点的常见应用场景//学习this调用该类的其他构造器Student s2 = new Student("楠楠",19);System.out.println(s2.getName());System.out.println(s2.getAge());System.out.println(s2.getSchool());}
}
3.多态
(1)认识与入门
多态是在继承/实现情况下的一种现象,表现为:对象多态,行为多态。
前提:有继承/实现关系,存在父类引用子类对象,存在方法重写(才会有行为多态)
(2)使用好处
- 在多态形式下,右边对象是解耦合的,更便于拓展和维护。
- 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性强,更便利
*多态下会产生下一个问题 :多态下不能使用子类的独有功能。
package d2_OPP;public class Student extends People{@Overridepublic void run(){System.out.println("学生跑的很快");}public void text(){System.out.println("学生需要考试");}
}package d2_OPP;public class Teacher extends People {@Overridepublic void run(){System.out.println("老师跑的气喘嘘嘘");}public void teach(){System.out.println("老师需要教书");}
}package d2_OPP;public class Text {public static void main(String[] args) {//理解多态的好处//好处1 可以实现解耦合 右边对象随时切换 后续业务随之改变People p1 = new Student(); //new Studentp1.run();//p1.text();Student s = new Student();go(s);Teacher t = new Teacher();go(t);}//好处2 可以使用父类类型的变量作为形参,可以接收一切子类对象public static void go(People p){}}
(3)多态下的类型转换问题
类型转换:(解决多态下不能调用子类独有方法的问题)
- 自动类型转换:父类 变量名 = new 子类();
- 强制类型转换:子类 变量名 = (子类)父类变量
强制类型看转换的一个注意事项:
- 存在继承/实现关系就可以在编译阶段进行强制类型转化,编译不报错
- 运行时,如果发现对象的真实类型与强转后的类型不同,会报类型转换异常(ClassCastException)的错误出来
- (使用关键字 instanceof 进行判断真实类型)
package d2_OPP;public class Text {public static void main(String[] args) {//理解多态的好处//好处1 可以实现解耦合 右边对象随时切换 后续业务随之改变People p1 = new Student(); //new Studentp1.run();//强制类型转化if(p1 instanceof Student) {Student s1 = (Student) p1;s1.text();}else {Teacher t2 = new Teacher();t2.teach();}//就可以执行独特功能Student s = new Student();go(s);Teacher t = new Teacher();go(t);}//好处2 可以使用父类类型的变量作为形参,可以接收一切子类对象public static void go(People p){if(p instanceof Student) {Student s1 = (Student) p;s1.run();}else {Teacher t2 = (Teacher) p;t2.run();}}}
4.final
(1)认识与了解
final关键字是最终的意思,可以修饰类,方法,变量
- 修饰类 :最终类 特点是不能被继承了
- 修饰方法:最终方法 特点是不能被重写了
- 修饰变量:该变量只能被赋值一次
- (final修饰基本类型的变量,变量存储的数据不能改变)
- (final修饰引用类型的变量 地址不能改变 但是地址指向的内容是可以改变的)
package d3_final;public class Text {public static void main(String[] args) {//final 修饰变懒 有且仅能赋值一次 /*变量一。局部变量二。成员变量1.静态成员变量2.实例成员变量 */final int a;a = 5;// a = 6; //第二次赋值会出错 保护数值}
}//1.final 修饰类,类不能被继承 (一般用于工作类)
final class A{}//class B extends A{}//2.final 修饰方法 方法不能被重写class C{public final void text (){}
}/*class D extends C{@Overridepublic void text(){}
}*/
(2)常量详解
- 使用了static final修饰的成员变量就称为常量
- 作用:通常用于记录系统的配置信息
注意:命名规范:大写英文字母,多个单词使用下划线
常量的优势和执行原理:
- 代码可读性好,可维护性也更好
- 编译后,常量会进行 “宏替换”
5.抽象类
(1)认识与入门
java 有一个关键字 abstract 抽象 用来修饰类和方法
package d4_abstrsact;
//抽象类
public abstract class A {//抽象方法 必须用abstract修饰,只有方法签名 一定不能有方法体public abstract void run();
}
抽象类的注意事项特点:
- 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。
- 类该有的成员成员变量,方法,构造器,抽象类都可以有。
- 抽象类最主要的特点,抽象类不能创建对象,仅作为一特殊的父类让子类继承并实现。
- 一个类继承抽象类必须重写抽象类的全部抽象方法。否则这个类也必须定义为抽象类。
(2)使用好处
父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义为抽象方法。交给子类去重写实现。我们设计这样的抽象类就是为了更好的支持多态。
package d4_abstrsact;public abstract class Animal {private String name;public abstract void cry();public String getName() {return name;}public void setName(String name) {this.name = name;}
}package d4_abstrsact;public class Dog extends Animal {@Overridepublic void cry() {System.out.println("汪汪汪、、、");}
}package d4_abstrsact;public class Cat extends Animal{@Overridepublic void cry() {System.out.println("喵喵喵。。。");}
}package d4_abstrsact;public class Text {public static void main(String[] args) {Cat c = new Cat();Dog d = new Dog();c.cry();d.cry();}
}
(3)应用场景
模板方法设计模式
解决方法中存在重复代码的问题
写法:
- 1.定义一个抽象类
- 2.在里面定义两个方法;
一个是模板方法:把相同的代码放里面去
一个是抽象方法:具体实现交给子类实现
package d5_abstract;public class Text {public static void main(String[] args) {//目标:搞清楚抽象类的应用场景之一,经常用来设计模板方法设计模式//场景 :学生,老师都要写一篇作文//开头 结尾一样,正文自由发挥Teacher t = new Teacher();t.write();}
}package d5_abstract;public abstract class People {// 设计模板方式方法//定义一个模板方法public void write() {System.out.println("\t\t\t\t\t《我的爸爸》");//模板方法不清楚正文部分怎么写,但是它知道子类要去写System.out.println(writeMain());System.out.println("有这样的爸爸太好了");
}public abstract String writeMain();}package d5_abstract;public class Teacher extends People {public String writeMain() {return "也是非常厉害";}
}package d5_abstract;public class Student extends People {@Overridepublic String writeMain() {return " 厉害";}
}
建议 final关键字修饰模版方法 :
- 模板方法直接给对象使用,不能被子类重写
- 一旦子类重写了模板方法,模板方法就失效了
6.接口
(1)概述
java 提供了一个关键字interface ,用这个关键字可以定义一个特殊的结构:接口
接口中没有构造器和代码块之类的东西 ,接口也不可以创建对象。接口是被类实现(implements)的,实现接口的类称为实现类。
一个类可以实现多个接口(接口可以理解成干爹),实现类实现多个接口。必须重写完全部接口的全部抽象方法,否则实现类需要定义为抽象类
接口的好处:
弥补了类单继承的不足,一个类同时实现多个接口。(拓展功能)
让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现
package d6_interface;public class Text {public static void main(String[] args) {//目标:搞清楚使用接口的好处Driver s = new A();s.drive();}
}class A extends Student implements Driver {@Overridepublic void drive(){System.out.println("会开车");}
}class Student{}interface Driver {void drive();
}interface Singer{void sing();
}
(2)综合案例
需求:
请涉及一个班级学生的信息管理模块,学生的数据有:姓名,性别,成绩,
功能1:要求打印出全班学生的信息。功能2:要求打印出全班学生的平均成绩。
————————————————————————————————————————
以上业务的实现有多套方案。例如:
第一套方案能打印班级全部学生的信息,能打印班级全部学生的平均分。
第二套方案能打印出班级全部学生的信息(包括男女人数)。能打印班级全部学生的平均分(要求是去掉最高分,最低分)。
package d7_interface_demo;import java.util.ArrayList;public class student_mpl1 implements studentOperator {@Overridepublic void printAllInfo(ArrayList<Student> students){System.out.println("======全班全部学生信息======");for (int i = 0; i < students.size(); i++) {Student s = students.get(i);System.out.println("姓名:"+s.getName());System.out.println("性别:"+s.getSex());System.out.println("成绩:"+s.getScore());System.out.println("======================");}System.out.println("打印完毕");}@Overridepublic void printAverageScore(ArrayList<Student> students){double allScore = 0.0;for (int i = 0; i < students.size(); i++) {Student s = students.get(i);allScore += s.getScore();}System.out.println("平均分:"+(allScore/students.size()));}
}
package d7_interface_demo;import java.util.ArrayList;public class student_mpl2 implements studentOperator{@Overridepublic void printAllInfo(ArrayList<Student> students){System.out.println("======全班全部学生信息======");int count1 = 0;int count2 = 0;for (int i = 0; i < students.size(); i++) {Student s = students.get(i);System.out.println("姓名"+s.getName());System.out.println("性别"+s.getSex());if(s.getSex() == '男'){count1++;}else{count2++;}System.out.println("成绩"+s.getScore());System.out.println("======================");}System.out.println("男生人数:"+count1);System.out.println("女生人数:"+count2);System.out.println("班级总人数"+students.size());System.out.println("打印完毕");}@Overridepublic void printAverageScore(ArrayList<Student> students){double allScore = 0.0;double max = students.get(0).getScore();double min = students.get(0).getScore();for (int i = 0; i < students.size(); i++) {Student s = students.get(i);allScore += s.getScore();if(s.getScore() > max){max = s.getScore();}if(s.getScore() < min){min = s.getScore();}}System.out.println("学生的最高分:"+max);System.out.println("学生的最低分:"+min);System.out.println("平均分:"+((allScore-max-min)/students.size()-2));}
}
package d7_interface_demo;import java.util.ArrayList;public interface studentOperator {void printAllInfo(ArrayList<Student> students);void printAverageScore(ArrayList<Student> students);
}
package d7_interface_demo;import java.util.ArrayList;public class ClassManager {private ArrayList<Student> students = new ArrayList<>();private studentOperator stuopera = new student_mpl1();//private studentOperator stuopera = new student_mpl2();public ClassManager(){students.add(new Student("陈平安",'男',88));students.add(new Student("刘羡阳",'男',100));students.add(new Student("顾璨",'男',90));students.add(new Student("宁姚",'女',100));}//打印全班全部学生信息public void printInfo(){stuopera.printAllInfo(students);}//打印全班全部学生的平均分public void printScore(){stuopera.printAverageScore(students);}
}
package d7_interface_demo;public class Text {public static void main(String[] args) {//目标:完成班级学生信息管理的案例ClassManager opera = new ClassManager();opera.printInfo();opera.printScore();}
}
(3)接口的细节
JDK8后接口新增的三种方法(增强接口功能,便于系统维护)
package d8_jdk8;public interface A {//1.默认方法:必须使用default修饰,默认会被public修饰//实例方法:对象访问 ,必须通过实现类default void text1(){System.out.println("默认方法");text2();}//2.私有方法:必须使用private修饰//jkk9后支持 //在接口中调用private void text2(){System.out.println("私有方法");}//3.静态方法:必须使用static修饰//只能使用接口名来调用public static void text3(){System.out.println("静态方法");}
}
接口的多继承
便于类去实现
接口的注意事项(了解)
- 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
- 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现.
- 一个类,继承了父类,又同时实现了接口。父类中和接口中有同名的默认方法实现类会优先用父类的。
- 一个类实现了多个接口,多个接口中存在同名的默认方法可以不冲突,这个类重写该方法即可。
7.内部类
(1)内部类概述
内部类是类中的五大成分之一(成员变量,方法,构造器,内部类,代码块),一个类定义在另一个类的内部,这个类就是内部类
(2)成员内部类
类中的一个普通成员,类似前面学过的普通的成员变量,成员方法(注意访问特点)
注意事项:
1.jdk16后支持内部类创建静态成员变量
2.内部类创建对象的格式:外部类名.内部类名 对象名 = new 外部类 (...)new 内部类(...);
(3)静态内部类
有static修饰的内部类,属于外部类自己持有。
(4)局部内部类
局部内部类是定义在方法中,代码中,构造体等执行体(鸡肋语法)
(5)匿名内部类*
就是一种特殊的内部类;所谓匿名:指程序员不需要为这个类声明名字
使用场景: 通常作为一个参数传输给方法
实际应用场景:
package d2_inner;import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class Text4 {public static void main(String[] args) {//拓展:搞清楚匿名内部类在着真实开发中的使用场景//GUI编程//1.创建窗口JFrame win = new JFrame("登录界面");JPanel panel = new JPanel();win.add(panel);JButton btn = new JButton("登录");win.add(btn);// 给按钮绑定单击事件监听器btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JOptionPane.showMessageDialog(win,"欢迎");}});//最终的核心目的是:简化代码win.setSize(400,400);win.setLocationRelativeTo(null);win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);win.setVisible(true);} }
8.枚举
枚举是一种特殊类
(1)介绍
- 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每一个常量记住的都是枚举类的一个对象。
- 枚举类的构造器都是私有的(写与不写都只能是私有),因此枚举类对外不能创建对象。
- 枚举都是最终类,不可以被继承,枚举类中从第二行开始可以定义类的其他各种成员。
- 编译器为枚举类新增了几个方法,并且枚举类都是继承JAVA.long.Enum类。
package d3_enum;public class Text {public static void main(String[] args) {//目标 认识枚举A a1 = A.X ;System.out.println(a1);//枚举类提供一个一些额外的APIA[] as = A.values(); //拿到全部对象A a3 = A.valueOf("Z");System.out.println(a3.name());System.out.println(a3.ordinal()); //索引}
}
(2)应用场景
应用场景: 用来表示一组信息,然后作为参数进行传输
作为信息分类
9.泛型
(1)认识泛型
泛型:定义类,接口,方法时,同时声明了一个或者多个类型变量<E>,称为泛型类,泛型接口,泛型方法,统称为泛型
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力,这样可以避免强制类型转换,及其可能出现的异常
泛型的本质:把具体的数据类型作为参数传给类型变量
(2)泛型类
package d5_generics;public class List <E>{private Object [] arr = new Object[10];private int size;public boolean add(E e){arr[size++] = e;return true;}public E get (int index){return (E) arr[index];}
}
(3)泛型接口
package d5_generics;import java.util.ArrayList;public interface Data<T> {void add(T t);ArrayList<T> getByName(String name);
}
泛型接口的类型变量建议使用大写英文字母
(4)泛型方法,泛型通配符,上下限
package d5_generics;import java.util.ArrayList;public class Text3 {public static void main(String[] args) {//目标:掌握泛型方法的定义和使用String rs = test("java");Dog d = test(new Dog());System.out.println(d);}//泛型方法public static <T> T test (T t){return t;}//使用extends限制输入类型 是car或者car的子类public static <T extends car > void go(ArrayList<T> car){}//? 通用符 使用泛型可以代表一切类型 一样可以限制 ?extends car(上限) ?super car(下限)public static void go1(ArrayList<? extends car> car){}
}
(5)注意事项
擦除问题
泛型是工作在编译阶段的,一旦程序编译成class文件。Class文件中就不存在泛型了,这就是泛型擦除。(底层还是基于Object类型)
泛型不支持基本数据类型。只能支持对象类型(引用数据类型)。
学习时间:2024.8.4
相关文章:

JAVA—面向对象编程高级
学习了一定基础后,开始更加深入的学习面向对象,包含static,final两个关键字,面向对象编程三大特征之继承和多态。以及对于抽象类,内部类,接口,枚举,泛型的学习。 目录 1.static (…...

[BJDCTF2020]Mark loves cat1
打开题目 发现这么多链接,以为要一点点去找功能上的漏洞。当你源代码,dirsearch,抓包等等操作之后,发现什么都没有。所以这题又是一道源码泄露题,上GItHack。扫描结果如下 http://63f29a80-e08b-43ae-a6d0-8e70fb02ea…...

微信答题小程序产品研发-用户操作流程设计
在答题小程序中,用户流程是指用户从进入小程序开始,到完成答题、查看结果、进行练习等一系列操作的步骤。 这里我画了一张用户流程图,展示用户在小程序中的主要操作流程。以及对每个步骤的详细说明。这里分两种角色,用户和管理员…...

目标检测——YOLOv10: Real-Time End-to-End Object Detection
YOLOv10是在YOLOv8的基础上,借鉴了RT-DETR的一些创新点改进出来的 标题:YOLOv10: Real-Time End-to-End Object Detection论文:https://arxiv.org/pdf/2405.14458源码:https://github.com/THU-MIG/yolov10 1. 论文介绍 在过去的几…...

堡垒机简单介绍
堡垒机(Bastion Host),也被称为跳板机、跳板服务器或堡垒服务器,是一种在网络安全中扮演重要角色的设备或服务。以下是关于堡垒机的详细介绍: 一、定义与功能 堡垒机是一种用于控制和管理网络安全的重要工具…...

【星闪开发连载】WS63E 星闪开发板和hi3861开发板的对比
此次星闪开发者体验官活动使用的开发板都是NearLink_DK_WS63E开发板,它和NearLink_DK_WS63开发板的区别在于具有雷达感知功能。从开发板的照片也可以看到WS63E有一个雷达天线接口。 我们把WS63E开发板和hi3861开发板的功能做了简单的对比,见下表。 参数…...

Python接口自动化测试框架(实战篇)-- Jenkins持续集成
文章目录 一、前言二、[Jenkins](https://www.jenkins.io/)2.1、环境搭建2.2、插件准备2.3、创建job2.4、小结2.5、构建策略2.6、报告展示2.7、扩展三、总结一、前言 温馨提示:在框架需要集成jenkins的时候,一定要注意环境切换问题,如果jenkins和开发环境是同样的系统且都有…...

【leetcode】根据二叉树创建字符串、二叉树的前中后遍历(非递归链表实现二叉树)
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:数据结构、LeetCode专栏 📚本系…...

【RabbitMQ】RabbitMQ交换机概述
一、交换机的类型 RabbitMQ提供了以下四种主要类型的交换机: 直连交换机(Direct Exchange) 特点:直连交换机是最基本的交换机类型,它根据完全匹配的路由键(Routing Key)将消息路由到绑定的队列…...

ROS2从入门到精通4-6:路径平滑插件开发案例(以B样条曲线平滑为例)
目录 0 专栏介绍1 ROS2路径平滑器介绍2 平滑器插件编写模板2.1 构造平滑器插件类2.2 注册并导出插件2.3 编译与使用插件 3 基于B样条曲线的路径平滑 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2…...

Tensorflow训练视觉模型(CPU)
目录 零、模型下载 一、清理C盘 二、 配置环境 三、运行项目前提操作 (1)根据自己的项目设置路径。每次激活虚拟环境(tensorflow115)都得重设一次 (2)执行setup 这个项目的路径移动了位置也需要重设一…...

从根儿上学习spring 十 之run方法启动第四段(4)
我们接着上一节已经准备开始分析AbstractAutowireCapableBeanFactory#doCreateBean方法,该方法是spring真正开始创建bean实例并初始化bean的入口方法,属于核心逻辑,所以我们新开一节开始分析。 图12 图12-530到536行 这几行的主要就是创建b…...

如果我的发明有修改,需要如何处理?
如果我的发明有修改,需要如何处理?...

java:File与MultipartFile互转
1 概述 当我们在处理文件上传的功能时,通常会使用MultipartFile对象来表示上传的文件数据。然而,有时候我们可能已经有了一个File对象,而不是MultipartFile对象,需要将File对象转换为MultipartFile对象进行进一步处理。 在Java中…...

高级java每日一道面试题-2024年8月04日-web篇-如果客户端禁止cookie能实现session还能用吗?
如果有遗漏,评论区告诉我进行补充 面试官: 如果客户端禁止cookie能实现session还能用吗? 我回答: 当客户端禁用了Cookie时,传统的基于Cookie的Session机制会受到影响,因为Session ID通常是通过Cookie在客户端和服务器之间传递的。然而,尽…...

leetcode 107.二叉树的层序遍||
1.题目要求: 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)2.此题步骤: 1.先创建好队列,出队和入队函数: //创建队列 typedef struct que…...

C++在网络安全领域的应用
前言: 在当今的数字化时代,网络安全已经成为一个至关重要的领域。随着网络威胁和攻击手段的不断演变,开发高效、安全的系统和工具变得尤为重要。C作为一种功能强大且高性能的编程语言,在网络安全领域发挥着不可替代的作用。本文简…...

Chapter 26 Python魔术方法
欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能! 文章目录 前言一、什么是魔术方法?二、常见的魔术方法① __init__构造方法② __str__字符串方法③ __lt__比较方法④ __le__比较方法⑤ __eq__比较方法 前言 本章将详细讲…...

基于Transformer的语音识别与音频分类
重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…...

leetcode数论(1362. 最接近的因数)
前言 经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。 数论包含最大公约数(>2个数)、最大公约数性质、最小公倍数、区间范围质因素计数(最下间隔)、质因素分解、判断质数、平方根、立方根、互质、同余等等。 描述 给…...

sqli-labs-master less1-less6
目录 通关前必看 1、判断是否存在sql注入以及是字符型还是数值型: 2、各种注入方式以及方法 有回显型: 报错注入(只有ok和no的提示以及报错提示): 详细思路,后面的题都可以这样去思考 关卡实操 less…...

力扣287【寻找重复数】
给定一个包含 n 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。 你设计的解决方案必须 不修改 数组 nums 且只用常…...

【2024蓝桥杯/C++/B组/传送阵】
题目 问题代码 #include<bits/stdc.h> using namespace std;const int N 1e610; int n; int porter[N]; int ans; int sign[N]; bool used;void dfs(int now, int cnt) {if(sign[now] && used){ans max(ans, cnt);return;}if(!sign[now]){cnt, sign[now] 1; …...

(四十一)大数据实战——spark的yarn模式生产环境部署
前言 Spark 是一个开源的分布式计算系统。它提供了高效的数据处理能力,支持复杂的数据分析和处理任务,是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。Spark Core:实现了Spark的基本功能,包含任务调度、内存管理、错误…...

【深度学习实战(53)】classification_report()
classification_report()是python在机器学习中常用的输出模型评估报告的方法。 classification_report()函数介绍 classification_report()语法如下:classification_report( y_true, y_pred, labelsNone, …...

计算机网络基础之网络套接字socket编程(初步认识UDP、TCP协议)
绪论 “宿命论是那些缺乏意志力的弱者的借口。 ——罗曼.罗兰”,本章是为应用层打基础,因为在写应用层时将直接通过文本和代码的形式来更加可视化的理解网络,本章主要写的是如何使用网络套接字和udp、tcp初步认识。 话不多说安…...

手撕Python!模块、包、库,傻傻分不清?一分钟带你弄明白!
哈喽,各位小伙伴们!今天咱们来聊聊Python中的模块、包和库,很多新手小白经常搞混,别担心,看完这篇,保证你一分钟就能搞定! 打个比方: 模块 (Module): 就好比是一块块乐高积木&#…...

Linux--序列化与反序列化
序列化 序列化是指将数据结构或对象状态转换成可以存储或传输的格式的过程。在序列化过程中,对象的状态信息被转换为可以保持或传输的格式(如二进制、XML、JSON等)。序列化后的数据可以被写入到文件、数据库、内存缓冲区中,或者通…...

使用C#和 aspose.total 实现替换pdf中的文字(外语:捷克语言的pdf),并生成新的pdf导出到指定路径
程序主入口: Program.cs using System; using System.Collections.Generic; using System.Configuration; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks;namespace PdfEditor {public class Progra…...

【Material-UI】Autocomplete中的高亮功能(Highlights)详解
文章目录 一、简介二、实现高亮功能示例代码代码解释 三、实际应用场景1. 搜索功能2. 表单自动完成 四、总结 在现代Web开发中,提供清晰的用户反馈是提升用户体验的重要组成部分。Material-UI的Autocomplete组件通过高亮功能,帮助用户快速识别搜索结果中…...