Java语法高级部分

本文是承接上文Java中级语法部分继续书写

文章目录

前言

1.类变量(静态变量)与类方法

1.1类变量的内存布局

1.2类变量细节讨论

1.3类方法(静态方法)

 1.4类方法注意事项

 2.Main语法说明

 3.代码块(初始化块)

 3.1代码块使用细节

3.2代码块重点(静态>普通>构造器)

4.单例设计模式 

4.1单例设计模式(饿汉式)可能导致浪费

4.2懒汉式单例设计模式

5.final关键字使用 

6.抽象类Abstract

7.抽象类的实现--模板设计模式

8.接口

8.1接口介绍

8.2接口深入讨论

8.3接口VS继承

9.内部类

9.1局部内部类的使用:

9.2匿名内部类Anonymous

9.3匿名内部类的实践

9.4成员内部类

9.5静态内部类:

10枚举类

10.1自定义类实现枚举

10.2使用enmu关键字实现枚举

10.3enum关键字实现枚举入门

11.注解的用处

总结

前言


提示:以下是本篇文章正文内容,下面案例可供参考

1.类变量(静态变量)与类方法

类变量:语法:访问修饰符 static 数据类型 变量名(public static int count);.该变量最大特点是会被所属类的所有对象实例共享

类变量除了可以使用实例对象.类变量访问外还可以通过类名.类变量访问(要注意访问权限)

1.1类变量的内存布局

jdk8以后静态变量就放在堆里的一个class对象里。注意static是同一个类的所有对象共享,在类加载的时候就生成了。所以可以用类名.类变量访问,即使没有创建对象实例也可以访问!它在内存中仅有一个,且JVM也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问它。

但是实例变量则不同,它是伴随着实例的,每创建一个实例就会产生一个实例变量,它与该实例同生共死。

1.2类变量细节讨论

类变量与实例变量(普通变量)区别:类变量是同一个类所有对象共享,而实例变量是每个对象独享。类变量生命周期随着类加载开始,随着类消亡而结束

1.3类方法(静态方法)

语法:访问修饰符 static 数据返回类型  方法名()

类方法的调用:类名.类方法、对象名.类方法

同一个类共享同一个方法

 1.4类方法注意事项

 类方法和普通方法一样随着类的加载而加载,将结构信息存储在方法区。

类方法里没有this参数,普通方法有this。

非静态方法不可以通过类名调用。

类方法中不可以使用与对象有关的参数this、super,因为在类加载时的类方法,没有对象

类方法只能访问静态变量、静态方法

普通成员方法既可以访问非静态成员也可以访问静态成员(类名.静态方法/类名.静态属性)

 2.Main语法说明

main方法是java虚拟机调用,必须用public,而且java虚拟机执行main方法时不必创建对象,所以必须是static。 

main方法中,接收String类型的数组参数,该数组中保存着执行java命令时传递给所运行的类的参数

 在静态main()方法中,可以直接调用main方法所在类的静态方法或静态属性,但是不能直接访问所在类的非静态成员,必须创建该类的实例对象才可以访问非静态成员

 3.代码块(初始化块)

代码块是类的一部分,类似于方法,将逻辑语句封装在方法体内,通过{}包围起来,与方法不同,代码块没有方法名没有返回,没有参数。只有参数,而且不用通过类或者对象显示调用,而是在加载类时,或创建对象时隐式调用

基本语法[修饰符]{方法体};。

修饰符可选要写只能写static,代码块可以是静态,也可以是非静态代码块

代码块是不管调用哪个构造器,都先会调用代码块,代码块优先于构造器

构造代码块是给所有对象进行统一初始化。而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

 3.1代码块使用细节

1.static代码块,也叫静态代码块,对类进行初始化,它随着类的加载而执行,(加载类的情况:a:创建对象实例时、b:创建子类对象实例,父类也会被加载,而且父类先加载、c:使用类的静态成员时静态代码块都会执行)并且只会执行一次。

如果是普通代码块,每创建一个对象就执行一次代码块。(只于对象有关)

普通代码块在创建对象实例时会被隐式调用,创建一次‘执行一次代码块。但是如果只是使用类的静态成员时,普通代码块不会执行。静态代码块执行。

3.2代码块重点(静态>普通>构造器)

在创建一个对象时的顺序(1.调用静态代码块和静态属性初始化,静态属性和静态代码块优先级一样。如果有多个静态代码块和多个静态属性初始化,则按他们定义顺序调用2.调用普通代码块和普通属性初始化时普通代码块和普通属性初始化优先级一样,如果有多个普通代码块和多个普通属性初始化按照定义顺序来调用)

public class CodeBlockDetail {
    public static void main(String[] args)
    {
        AA a=new AA();
        a.showinfo();
    }
}

class AA
{
    public int m=20;
    public static int n=10;

    {
        System.out.println("这是AA普通代码块");
    }

    public static void showinfo()
    {
        System.out.println("这是AA静态方法");
    }
    static
    {
        System.out.println("这是AA静态代码块");
    }
    public AA()
    {
        System.out.println("这是AA构造器");
    }
}

构造器最前面,除了隐含super调用父类构造器,还有调用普通代码块。静态相关的代码块和属性初始化,在类加载时,就执行完毕。

当有继承关系时,执行顺序如下:

当创建子类对象有继承关系时,他们的静态代码块、静态属性初始化、普通代码块、普通属性初始化、构造方法。

父类静态代码块、静态属性初始化执行(优先级一样,按照定义顺序来)

子类静态代码块、子类静态属性初始化执行(优先级一样,按照定义顺序来)

父类普通代码块、父类普通属性初始化执行(优先级一样,按照定义顺序来)

父类构造方法

子类普通代码块、子类普通属性初始化执行(优先级一样,按照定义顺序来)

子类构造方法

静态代码块只能直接调用静态成员,但是普通代码块可以调用任意

4.单例设计模式 

单例设计模式就是单个实例,采用一定的方法保证整个软件系统中,对某个类只存在一个对象实例,并且该类只提供一个取得对象实例的方法

4.1单例设计模式(饿汉式)可能导致浪费

饿汉式单例模式步骤:1.将构造器私有化(防止外部直接new),2.类的内部创建唯一对象,该对象是static(这样只会执行一次),3.向外部暴露静态公共方法返回对象也要是static修饰的不然必须用new对象访问,4.代码实现

public class SingleTon01 {
    public static void main(String[] args)
    {
            GirlFriend instance=GirlFriend.getInstance();//通过方法获取对象gf=instance
            System.out.println(instance);
//            System.out.println(instance.toString());
            System.out.println(GirlFriend.n1);

    }
}

class GirlFriend{
    private String name;
    public static int n1=100;
    //如何保证只能创建一个GirlFriend对象
    //构造器私有化,这样main不能随意new对象
    private GirlFriend(String name) {
        this.name = name;
    }
    //类的内部创建对象,私有的想访问就只能静态的这样类.方法即可调用
    private static GirlFriend gf=new GirlFriend("小杨");//这里是饿汉式特点,gf可能没创建,但是已经想用了。
    // 那就用Girlfriend,因为这个在类加载时就会有产生对象,用类名.静态访问
    //饿汉式造成创建了但是没有造成资源浪费
    //提供一个公共的static方法(static方法可以访问static类型的,若方法不是static,调用时必须用对象调用),返回gf对象
    public static GirlFriend getInstance()
    {
        return gf;
    }

    @Override
    public String toString() {
        return "GirlFriend{" +
                "name='" + name + '\'' +
                '}';
    }
}

4.2懒汉式单例设计模式

1.构造器私有化

2.定义一个static静态对象

3.提供public的static方法,返回一个Cat对象

4.懒汉式只有当用户使用getinstance()才会返回cat对象,当再次调用时,还是返回上一次cat对象

public class SingleTon02 {
    public static void main(String[] args)
    {
        System.out.println(Cat.n1);//这里只打印n1,不会执行Cat构造器,因为只是加载类
        Cat instance=Cat.getInstance();//实例化对象
        System.out.println(instance);
        instance.toString();
    }
}
class Cat
{
    private String name;
    public static int n1=200;
    //构造器私有化
    private Cat(String name) {
        System.out.println("Cat构造器执行");
        this.name = name;
    }

    private static Cat cat;//定义一个static静态属性对象默认为null
    //提供pubilc的static方法可以返回一个Cat对象
    public static Cat getInstance()
    {
        if(cat==null)//保证只会创建一个对象,且用到才创建这个对象。
        {
            cat=new Cat("小花猫");
        }
        return cat;
    }

    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                '}';
    }

}

5.final关键字使用 

final(可以理解为把变量或者方法上锁)可以修饰类、属性、方法和局部变量。

final使用场景:1.当希望类不被继承,可以用final修饰类 final class name{}

                         2.不希望父类的某一个方法被重写可以使用final修饰方法public final void hi(

                         3.当不希望类的某一个属性被修改,可以使用final修饰,public final double x

                         4.当不希望某个局部变量(方法里)被修改,使用final修饰,

final修饰的属性一般是常量,用大写XX_XX_XX,final修饰的属性在定义时,必须赋值,并且以后不可以修改。被final修饰的常量会放入常量池(整数-127-128是默认加载到常量池里的)

当final修饰的是一个基本数据类型数据时, 这个数据的值在初始化后将不能被改变; 当final修饰的是一个引用类型数据时, 也就是修饰一个对象时, 引用在初始化后将永远指向一个内存地址, 不可修改. 但是该内存地址中保存的对象信息, 是可以进行修改的.

public static void main(String[] args) {
    final Person p = new Person(20, "zk");
    p.setAge(18);   //可以修改p对象的数据
    System.out.println(p.getAge()); //输出18

赋值可以在(定义变量时、构造器中、代码块里),若final修饰的属性是静态的,则初始化赋值位置只能在(定义时、在静态代码块,不可以在构造器赋值),final类不可以继承,但是可以实例化对象,如果类不是final类,有final方法,此方法不能被重写,但是可以继承。

若一个类已经是final类了,就没必要再将方法修饰为final方法

final不能修饰构造器,final与static往往搭配使用,不会导致类加载,不会加载static代码块、static修饰的信息了

包装类String、double、Integer、Float、Boolean都是final类,无法继承

6.抽象类Abstract

当父类某些方法,需要申明,但是有不确定如何实现时(没有方法体),

可以将其声明为抽象方法abstract public void 方法名(),那么这个类就是抽象类abstract class 类名{},并让子类来实现

抽象类细节:抽象类不可以实例化,抽象类不一定包含抽象方法,也可以有具体实现的方法

abstract只能修饰类和方法

抽象类的本质还是类,所以可以有任意成员(非抽象方法、构造器、静态属性)

抽象方法不可有代码主体。

一旦有抽象方法那么该类必定是抽象类,反过来未必。

如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,所谓实现只要有方法体就好{}空的也可以,除非他自己也申明了abstract类

抽象方法不能使用private、final、static修饰,因为这些关键字和重写违背

这里我就解释static为什么不能与abstract:因为首先static修饰方法为静态方法,若访问的话是要用类名.方法来访问,我只能这样理解,抽象类只是抽象没有类加载,不能实现类名.方法访问。还有就是,static方法是实现的就必须有方法体,即已经实现了,而抽象方法不能有方法体,也就不是抽象方法了

7.抽象类的实现--模板设计模式

需求:

 在模板父类类里,具体实现的方法调用了抽象方法。在子类继承后,要重写抽象方法

然后在测试类里具体运行时,new子类调用方法

abstract public class Template {

    public abstract void job();
    public  void calculate()//具体实现方法调用抽象方法
    {
        long start=System.currentTimeMillis();
        job();
        long end=System.currentTimeMillis();
        System.out.println("执行时间为"+(end-start));
    }
}

public class A extends Template {
    @Override
    public void job() {
        long num=0;
        for(int i=1;i<1000000;i++)
        {
            num+=i;
        }
    }
}

public class TestTemplate {
    public static void main(String[] args)
    {
        Template t=new A();
        t.calculate();
        //或者
        A a=new A();
        a.calculate();//这两个都涉及到动态绑定机制,因为calculate是父类有,
        // 去父类找到后执行到job是在子类,因为运行类型是A,去A类实现job
    }
}

8.接口

定义完interface接口文件后,在java文件类名public class Phone implement 接口名,

具体设备类Phone然后实现接口方法。,在电脑类编写方法,引入接口形参,调用接口类的方法

public interface interface1 {
    public void start();
    public void end();
}

public class Phone implements interface1 {
    @Override
    public void start() {
        System.out.println("手机开始工作");
    }

    @Override
    public void end() {
        System.out.println("手机停止工作");
    }
}

public class Computer {
    public void work(interface1 interface11)
    {
        interface11.start();//通过接口实现方法
        interface11.end();
    }
}

    public static void main(String[] args)
    {
        Phone phone=new Phone();
        Computer computer=new Computer();
        computer.work(phone);
    }
}

8.1接口介绍

接口就是给出一些没有具体实现的方法,封装在一起,根据具体情况把这些方法写出。

接口语法:interface 接口名{属性;方法(抽象方法、默认实现方法、静态方法);}

class 类名 implements 接口{自己属性,自己方法,必须实现的接口所有抽象方法}

注意在jdk8后接口里可以有默认实现方法即:

        在接口中,可以定义这样的默认实现方法default public void ok(){}具体实现了

        接口定义静态方法 public static void okk(){},具体实现的

        接口定义抽象方法不用加abstract,默认省略 public void okkk();

8.2接口深入讨论

1.接口不可以实例化,本身就是抽象的。2.接口中所有方法都是public,3.接口中抽象方法可以不用abstract修饰。。4.一个普通类实现接口,该类必须将接口所有方法都实现(使用alt+enter,点击impelment methods)

5.抽象类实现接口,可以不用具体实现接口的方法。6.一个类可以同时实现多个接口

6.接口中的属性只能是final的,而且是public static final修饰符。比如int a=1实际上是public static final int a=1(由于final不可再赋值,必须初始化);

7.接口中属性的访问形式:接口名.属性名

8.一个接口不能继承其他类,但是可以继承多个别的接口

9.接口修饰符只能是public和默认(与类的修饰符一样)

10.接口也具有多态特性,可以定义多态数组接口类型数组 接口名[] 接口=new 接口名[10];

8.3接口VS继承

接口实现是对java单继承机制的补充扩展功能。class a extends b implement c,d

接口类型的变量可以指向,实现该接口的类的对象实例(多态向上转型)

比如:IG由Teacher类实现,在main方法里可以 IG ig=new Teacher();

如果IG继承了IH接口,而Teacher类实现了IG接口,那么实际上相当于Teache也实现了IH接口  IH  ih=new Teacher()这就是接口多态传递现象

interface A{
    int x=0;//等价与public static final int x=0;
}
class B{
    int x=1;
}
class C extends B implements A{
    public void Px()
    {
        System.out.println(super.x);//或者A.x
    }
    public static void main(String[] args)
    {
        new C().Px();
    }
}//如果是super.x结果是1,A.x结果是0

9.内部类

一个类的内部又完整嵌套另一个类结构,被嵌套的类称为内部类。嵌套其他类的称为外部类

类的5部分(属性、方法、构造器、代码块、内部类)

内部类基本语法:class  Outer{   class Inner{内部类}     }    class  Other{外部其他类}

内部类有四种:     根据定义在外部类局部位置上(比如方法内、代码块):局部内部类(有类名)、匿名内部类(没有类名)

                        定义在外部类的成员位置上:成员内部类(没有static)、静态内部类(使static)

9.1局部内部类的使用

1.可以直接访问外部类所有成员,包括私有。2.局部内部类不能添加访问修饰符,但是可以添加final修饰。3.局部内部类作用域仅仅在定义他的方法中或代码块里。4.局部内部类是定义在外部类的局部位置上,可以直接访问外部类变量、方法。5.外部类访问内部成员时,外部类在方法里可以创建内部类对象,然后调用内部类方法。6.外部其他类不可以访问局部内部类,因为局部内部类地位只是一个局部变量。7.如果外部类与局部内部类的成员重名,默认遵循就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员访问)本质上就是外部类对象

/**
 * 演示局部内部类
 */
public class LocalInnerClass {
    public static void main(String[] args)
    {
        Outer02 outer02=new Outer02();
        outer02.m1();
    }
}
class Outer02{
    private int n1=100;
    //局部内部类定义在外部类的局部位置上,通常是方法里、方法块
    private void m2(){//私有方法
        System.out.println("这是外部类私有方法");
    };
    public void m1()
    {
        class Inner02{//局部内部类,本质上还是一个类
            private int n1=800;
            //可以直接访问外部类的所有成员,包含私有
            public void f1()
            {
                System.out.println(n1);//就近原则访问内部类n1
                System.out.println(Outer02.this.n1);//指定访问外部类属性Outer02.this本质上就是哪个对象调用了m1,Outer02.this就指向哪个
                m2();
            }
        }
        Inner02 inner02=new Inner02();//内部类在所属方法里new对象
        inner02.f1();
    }
}

9.2匿名内部类Anonymous

1.本质上是一个类,内部类。该类没有名字,匿名内部类是定义在外部类的局部位置(方法中、代码块)。

2.匿名内部类既是一个类的定义,同时还是一个对象。

匿名内部类基本语法:new 类或者接口(参数列表可无){类体};-------->看这里末尾是;

9.2.1基于接口的匿名内部类

是对于那种类只使用一次,后面不再使用了。

public class AnonymousClass {
    public static void main(String[] args)
    {
        Outer03 outer03=new Outer03();
        outer03.method();

    }
}

class Outer03 {//外部类
    private int n1 = 100;
    //局部内部类定义在外部类的局部位置上,通常是方法里、代码块
    public void method() {//私有方法
        System.out.println("这是外部类私有方法");
        IA tiger = new IA() {//这里new接口,直接对接口的方法重写。tiger编译类型是IA,运行类型就是匿名内部类Outer03$是匿名内部类,
        /*这里底层是有 class xxx implement IA{重写cry()}
        *匿名内部类Outer03$会立马创建对象Outer03$的实例,并且把地址返回给tiger
         *  匿名内部类使用一次就不能用了,但是这个对象tiger可以多次调用
         *  */
            @Override
            public void cry() {
                System.out.println("老虎叫");//
            }
        };
        tiger.cry();
        System.out.println("输出tiger的运行类型"+tiger.getClass());//运行类型就是匿名内部类Outer03$是匿名内部类,系统自动分配
    }
}
interface IA{
    public void cry();
}

9.2.2基于类的匿名内部类(有参数列表)

public class AnonymousClass {
    public static void main(String[] args)
    {
        Outer03 outer03=new Outer03();
        outer03.method();

    }
}
class Outer03 {//外部类
        //注意这是匿名内部类,father的编译类型是Father,运行类型是Outer04$2
        Father father=new Father("jack"){//这里形参列表会传给father构造器
            //这里底层是class Outer04$2 extends Father{}
            @Override//匿名内部类重写了test
            public void test() {
                super.test();
                System.out.println("匿名内部类重写的test");
            }
        };
        System.out.println("father的运行类型是="+father.getClass());
        father.test();
    }
}


class Father{
    public Father(String name){
    }
    public void test()
    {
        System.out.println("Father类的test");
    }
}

匿名内部类注意事项:

public class AnonymousInnerClassDetail {
    public static void main(String[] args)
    {
        Outer05 outer05=new Outer05();
        outer05.f1();
        System.out.println(outer05);
    }
}
class Outer05{
    private int n1=99;
    public void f1(){//创建一个基于类的匿名内部类
        Person person=new Person(){
            private int n1=88;
            @Override
            public void hi() {
                System.out.println("匿名内部类重写hi方法"+n1+"外部类的n1"+Outer05.this.n1);
                System.out.println(Outer05.this);//Outer05.this就是调用f1的对象
            }
        };
        person.hi();
        new Person(){//这是另一种写法,可以直接调用,因为匿名内部类本身返回的也是返回对象
            public void hi() {
                System.out.println("匿名内部类重写hi方法");
            }
        }.hi();
    }
}
class Person{
    public void hi()
    {
        System.out.println("Person hi()");
    }
}

9.3匿名内部类的实践

匿名内部类当作实参,直接传递

public class InnerClassExercise {
    public static  void main(String[] args)
    {
        f1(new IL(){//这里传的就是匿名内部类
            @Override
            public void show() {
                System.out.println("这是一副名画");
            }
        });
    }
    //静态方法,形参是接口类型
    public static void f1(IL il){
        il.show();
    }
}
interface IL{
    public void show();
}

public class InnerClassExercise02 {
    public static void main(String[] args)
    {
        CellPhone cellPhone=new CellPhone();
        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("懒猪起床啦");
            }
        });

        cellPhone.alarmclock(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙子上课了");
            }
        });
    }
}

interface Bell{
    void ring();
}
class CellPhone{
    public void alarmclock(Bell bell)//形参是接口类型
    {
        bell.ring();
    }
}

9.4成员内部类

1.成员内部类是定义在外部类的成员位置(相当于普通属性方法位置),并且没有static修饰。

2.可以直接访问外部类所有成员,包括私有

3.可以添加任意访问修饰符

4.作用域:与外部类的成员一样,在外部类的成员方法里,创建成员内部类对象,再调用成员内部类方法

5.成员内部类访问外部类:直接访问调用所有外部成员

6.外部类访问成员内部类:在外部类使用方法,先创建内部类对象,再访问

7.外部其他类访问成员内部类:{

  1. 用外部类对象去new内部类  形如Outer  Inner  inner=outer.new  Inner();
  2. 在外部类中,编写方法可以返回Inner内部类对象 ,

形如 public Inner getInnerInstance(){ return  new Inner(); }

然后外部其他类以Outer.Inner innsestance=outer.getInnerstance();

     3.如果成员内部类和外部类的成员重名,遵守就近原则访问。但是若想指定访问外部的成员,可以通过外部类名.this.属性

9.5静态内部类:

静态内部类是定义在外部类的成员位置,并且有static修饰。

1.静态内部类可以直接访问外部类所有静态成员(直接调用),包括私有,但是不能访问非静态成员。

2.可以添加任意访问修饰符(public、protected、默认、private)因为他的地位就是成员

3.作用域:同其他成员,为整个类体

4.外部类访问静态内部类访问方式:在方法里创建内部对象,再访问内部方法

5.外部其他类访问内部静态类{  方法1:外部类名.内部类  内部类对象=new 外部类.内部类()}(注意这里内部类不可以是private,)      红色部分之所以可以这样因为静态内部类是可以通过类名直接访问,满足权限 

方法2:使用方法返回一个静态内部类的对象实例  public Inner getInner(){return new Inner()}

这样在main方法里可以这样  Outer.Inner   inner=outer.getInner()

6.如果外部类与静态内部类成员重名,静态内部类访问属性时就近原则。如果想访问外部类成员,则可以使用(外部类.成员)访问

10枚举类

枚举类就是把具体对象一个一个例举出来的类,枚举是一组常量的集合。枚举是特殊的类里面只包含有限的特定对象

枚举实现两种方式:1.自定义类实现枚举 2.使用enum关键字实现枚举

10.1自定义类实现枚举

1.构造器私有化,防止直接new对象、2.去掉Set方法防止属性更改、3.在Season内部直接创建固定的对象、4.定义公共对象固定、5.优化加入final

枚举对象名通常全部大写,常量命名规范,枚举对象里可有多个属性

**
 * @author zk
 * @version 1.0
 */
public class Enumeration01 {
    public static void main(String[] args)
    {
        System.out.println(Season.SPRING);
    }
}
class Season {
    private String name;
    private String desc;
    //定义四个公共对象
    public final static Season SPRING=new Season("春天","暖和");
    public static Season SUMMER=new Season("夏天","热");
    public static Season AUTUMN=new Season("秋天","凉爽");
    public static Season WINTER=new Season("冬天","冷");
    private Season(String name, String desc)//构造器私有化,防止被new
    {
        this.name=name;
        this.desc=desc;
    }

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

10.2使用enum关键字实现枚举

1.在上一个类基础上,将class Season改为 enum Season

2.将 public final static Season SPRING=new Season("春天","暖和");  改为

SPRING("春天","暖和"),SUMMER("夏天","热")-->常量名(实参列表),如果有多个常量使用逗号隔开,这里必须知道调用哪个构造器

3.如果使用enum实现枚举,则这些常量对象必须写在最前面

4.可以有多个构造器。

/**
 * @author zk
 * @version 1.0
 */
public class Enumeration02 {
    public static void main(String[] args)
    {
        System.out.println(Season1.SPRING);
    }
}
enum  Season1{
    //使用enum实现枚举类
    SPRING("春天","暖和"),
    SUMMER("夏天","热"),
    What();//调用无参构造器创建对象用What、What()名字任意但是无参构造器必须存在
    private String name;
    private String desc;
    private Season1(String name, String desc)//构造器私有化,防止被new
    {
        this.name=name;
        this.desc=desc;
    }
    private Season1(){}

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

10.3enum关键字实现枚举入门

enum关键字开发枚举类时,默认继承Enum类

如果使用无参构造器创建枚举对象则实参列表和小括号可以省略

当有多个枚举对象,使用,间隔。最后一个使用;

枚举对象必须放在枚举类首行。

Enum类常用方法:

1.toString():是Enum类重写过,返回当前对象名,子类可以重写此方法,用于返回属性

2.name:返回对象名(常量名),子类不可以重写

3.ordinal:返回当前枚举对象位置号,默认0开始

4.enum类名.values:放回当前枚举类中所有常量

5.valueOf:将字符串转为枚举对象,要求字符串必须为已有常量名,否则报异常

6.compareTo:比较两个枚举常量,比较位置号   前-后

/**
 * @author zk
 * @version 1.0
 * 讲解enum类各种方法使用
 */
public class Enumeration03 {
    public static void main(String[] args)
    {
        Season2 spring=Season2.SPRING;
        Season2 summer=Season2.SUMMER;
        System.out.println(spring.name());//对象名
        System.out.println(spring.ordinal());//输出常量对象次序
        Season2[] values=Season2.values();//将enum类所有对象返回Season2[]数组,含有定义所有枚举对象存进values数组里
        for(Season2 season:values){//增强for循环,从values每次取一项,给season
            System.out.println(season);
        }
        Season2 summer1=Season2.valueOf("SUMMER");//将字符串转为枚举对象,但是字符串必须为已有常量名
        System.out.println(summer1);//根据输入SUMMER到Season2枚举类查找对象,如果找到了就返回,否则报错
        System.out.println(summer1==summer);//TRUE
        System.out.println(Season2.SPRING.compareTo(Season2.SUMMER));//比较枚举对象编号
        System.out.println(summer.compareTo(spring));//比较枚举对象编号,把spring编号减去summer编号
    }
}

enum  Season2{
    //使用enum实现枚举类
    SPRING("春天","暖和"),
    SUMMER("夏天","热"),
    What();//调用无参构造器创建对象用What、What()
    private String name;
    private String desc;
    private Season2(String name, String desc)//构造器私有化,防止被new
    {
        this.name=name;
        this.desc=desc;
    }
    private Season2(){}

    public String getName() {
        return name;
    }
    public String getDesc() {
        return desc;
    }
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

enum类不能继承其他类了,已经隐式继承Enum类,但是可以实现多个接口

11.注解的用处

被称为元数据,,用于修饰解释包、类、方法、属性、构造器、局部变量,和注释一样不会影响程序逻辑,但是注解会被编译运行,相当于嵌入在代码的补充信息。在JavaSE中用于标记过时功能

JavaEE用来配置应用程序的任何切面

JDK基本注解:@Override:限定某个方法,重写父类方法,该注解仅用于方法

@Deprecated:用于表示某个程序元素(类、方法)已过时,还是可以用

@SuppressWarning:抑制编译器错误   形如@SuppressWarning({"all"})全部忽视

SuppressWarning作用范围与放的位置有关,可以放方法、类上


总结

以上就是今天要讲的内容,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值