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("静态方法");}
}

        接口的多继承

便于类去实现

 接口的注意事项(了解)

  1. 一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承。
  2. 一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现.
  3. 一个类,继承了父类,又同时实现了接口。父类中和接口中有同名的默认方法实现类会优先用父类的。
  4. 一个类实现了多个接口,多个接口中存在同名的默认方法可以不冲突,这个类重写该方法即可。


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)介绍

  1. 枚举类的第一行只能罗列一些名称,这些名称都是常量,并且每一个常量记住的都是枚举类的一个对象。
  2. 枚举类的构造器都是私有的(写与不写都只能是私有),因此枚举类对外不能创建对象。
  3. 枚举都是最终类,不可以被继承,枚举类中从第二行开始可以定义类的其他各种成员。
  4. 编译器为枚举类新增了几个方法,并且枚举类都是继承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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/391730.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

原神自定义倒计时

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>原神倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;body {background: #0b1b2c;}}header {…

Javase--Date

1.Date简介 Date的学习: 1. java.util包下的类 2.用于日期、时间的描述 3. 实际上时距离一个固定时间点1970年1月1日00:00:00的毫秒数 4.我们常用的是格林威治时间:GMT UTC:世界调整时间 5.固定时间点:说的其实是本初子午线的时间。因此北京时间是1970年1月1日8:00:…

c++ 容器 vector

vector的意思就是向量&#xff0c;就是一个顺序表的意思&#xff0c;这个顺序表可以存任意的类型&#xff0c;因为其线性的内存特点&#xff0c;所以在stl里是经常被使用的存在。 vector vector既然要能储存任意的变量&#xff0c;那么就必须使用模板: 这里的T就是变量类型&a…

微信小程序之behaviors

目录 概括 Demo演示 进阶演示 1. 若具有同名的属性或方法 2. 若有同名的数据 3. 若有同名的生命周期函数 应用场景 最后 属性&方法 组件中使用 代码示例&#xff1a; 同名字段的覆盖和组合规则 概括 一句话总结: behaviors是用于组件间代码共享的特性, 类似一…

Docker简介 MacM1安装Docker

文章目录 1 Docker简介2 Docker VS 虚拟机1 Docker优势2 Docker用途 3 MacM1 下载安装Docker1 配置环境变量 4 配置Docker2 设置Docker资源3 设置Docker镜像 参考 1 Docker简介 Docker主要解决了软件开发和运行配置的问题&#xff0c;但是由于其功能的强大&#xff0c;也被应用…

LeetCode每日一题_600.不含连续1的非负整数

自己思路&#xff1a;暴力破解&#xff0c;但是超时 class Solution {public int findIntegers(int n) {int count0;String str2;for(int i 0;i<n;i){str2 Integer.toBinaryString(i);if(str2.contains("11")){count1;}}return n-count1;} }其他题解涉及动态规…

实战:使用Certbot签发免费ssl泛域名证书(主域名及其它子域名共用同一套证书)-2024.8.4(成功测试)

1、使用Certbot签发免费ssl泛域名证书 | One实战&#xff1a;使用Certbot签发免费ssl泛域名证书(主域名及其它子域名共用同一套证书)-2024.8.4(成功测试)https://wiki.onedayxyy.cn/docs/docs/Certbot-install/

利用 Angular 发挥环境的力量

一.介绍 您是否曾想过如何在不同的环境中为同一应用设置不同的颜色、标题或 API 调用&#xff1f;可以肯定的是&#xff0c;生产 API 和测试 API 是不同的&#xff0c;应谨慎使用。部署时&#xff0c;我们不会在项目的所有地方手动更改所有 API 调用。不应这样做&#xff0c;因…

【LeetCode每日一题】2024年8月第一周(下)

2024.8.03 中等 链接&#xff1a;3143. 正方形中的最多点数 &#xff08;1&#xff09;题目描述&#xff1a; &#xff08;2&#xff09;示例 &#xff08;3&#xff09;分析 题目中以s字符串中&#xff1a;相同的字母 为限制&#xff0c;要求方格内只包含不同字母对应的点位。…

YOLOv8添加注意力模块并测试和训练

YOLOv8添加注意力模块并测试和训练 参考bilibili视频 yolov8代码库中写好了注意力模块&#xff0c;但是yolov8的yaml文件中并没用使用它&#xff0c;如下图的通道注意力和空间注意力以及两者的结合CBAM&#xff0c;打开conv.py文件可以看到&#xff0c;其中包含了各种卷积块的…

【机器学习第7章——贝叶斯分类器】

机器学习第7章——贝叶斯分类器 7.贝叶斯分类器7.1贝叶斯决策论7.2 朴素贝叶斯分类器条件概率的m估计 7.3 极大似然估计优点基本原理 7.4 贝叶斯网络7.5 半朴素贝叶斯分类器7.6 EM算法7.7 EM算法实现 7.贝叶斯分类器 7.1贝叶斯决策论 一个医疗判断问题 有两个可选的假设&#…

校园商铺管理小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;在线咨询管理&#xff0c;咨询回复管理&#xff0c;交流论坛&#xff0c;系统管理 微信端账号功能包括&a…

【Verilog-CBB】开发与验证(4)——RS前向打拍器

引言 我们知道时序路径的建立时间收敛依赖于触发器之间的组合逻辑延迟&#xff0c;以及时钟周期。对于一个确定的设计一般来说&#xff0c;时钟频率不会有太多的让步&#xff0c;因此修时序的时候主要发力点就是减小触发器之间组合逻辑延迟。一方面可以通过组合逻辑优化来降低…

Chapter 22 数据可视化——折线图

欢迎大家订阅【Python从入门到精通】专栏&#xff0c;一起探索Python的无限可能&#xff01; 文章目录 前言一、Pyecharts介绍二、安装Pyecharts三、全局配置项四、绘制折线图 前言 在大数据时代&#xff0c;数据可视化成为了分析和展示数据的重要手段。Pyecharts 是一个基于 …

python open cv(图像处理的基本操作)

概要图 1读取图像 cv2.imread() 函数是OpenCV库中用于读取图像文件的函数。它有两个参数&#xff1a; 文件名&#xff1a;这是第一个也是必需的参数&#xff0c;它指定了要读取的图像文件的路径和文件名。这个路径可以是相对路径&#xff0c;也可以是绝对路径。 标志&#xf…

【practise】只出现一次的数字

现在给你一个数组&#xff0c;里面放了一些数字&#xff0c;里面都是两两成对&#xff0c;只有一个数字是单独的&#xff0c;要求找出其中只出现一次的数字。相必这道题是非常简单了&#xff0c;有很多解法比如说用暴力求解&#xff1f;比如说用位运算&#xff1f;甚至说用哈希…

【C++标准模版库】list的介绍及使用

list 一.list的介绍二.list的使用1.list 构造函数2.list 空间大小3.list 增删查改4.list 迭代器的使用1.正向迭代器2.反向迭代器 5.list 其他成员函数 三.vector与list关于sort性能的比较 一.list的介绍 C中的list标准模板库&#xff08;STL&#xff09;是C标准库中的一个重要组…

PCL1.11.0下载安装(Windows)

PCL1.11.0下载安装&#xff08;Windows&#xff09; PCL安装需要的几个模块如下图所示&#xff1a; 一、PCL1.11.0下载 PCL以1.11.0版本为例&#xff0c;打开下载连接&#xff08;PCL下载&#xff09; 下载PCL-1.11.0-AllInOne-msvc2019-win64.exe和pcl-1.11.0-pdb-msvc2019-…

Vue3 列表自动滚动播放(表头固定、列表内容自动滚动播放)+ vue3-seamless-scroll - 附完整示例

vue3-seamless-scroll&#xff1a;Vue3.0 无缝滚动组件&#xff0c;支持Vite2.0&#xff0c;支持服务端打包 目前组件支持上下左右无缝滚动&#xff0c;单步滚动&#xff0c;并且支持复杂图标的无缝滚动&#xff0c;目前组件支持平台与Vue3.0支持平台一致。 目录 效果 一、介绍…

腾讯云AI代码助手评测:如何智能高效完成Go语言Web项目开发

腾讯云AI代码助手评测&#xff1a;如何智能高效完成Go语言Web项目开发 &#x1f680; 文章目录 腾讯云AI代码助手评测&#xff1a;如何智能高效完成Go语言Web项目开发 &#x1f680;背景引言开发环境介绍腾讯云AI代码助手使用实例1. 代码补全2. 技术对话3. 代码优化4. 规范代码…