第六章·类和对象

类和对象

面向对象

对象概念

是一种编程思想

(1) 真实的世界由很多大大小小的对象组成,这些对象是有生命的个体,也可以是没有生命的个体组成,除此之外,抽象的概念也可以称为对象

(2) 真实世界由两部分组成:

–对象

–对象之间的关系

对象是系统中用来描述客观事物的实体,是构成系统的基本单元


对象的两个特征

属性

行为

例子:

人(对象) 属性:人的生理特征,人的性格

​ 行为:吃饭,走路等


面对对象的本质

是以类(class)的方式组织代码,以对象的形式封装数据


面向对象和面向过程的区别


代表语言不同

面向对象:Java

面向过程:c语言


通过吃饭问题解释面向对象与面向过程的区别

  • 面向对象:打开美团->选择食物->填写地址下单->支付->骑手送达->吃饭

  • 面向过程:煮饭->买菜->洗菜->切菜->炒菜->吃饭

解释:面向过程是需要一步一步都执行,对于面向对象来说不追求过程,只看结果


面向对象编程(oop)

是一种编程方法论


面向对象的三大特性

  • **封装:**是面向对象程序设计的核心思想,属性私有,getset。它将数据和操作这些数据的方法捆绑在一起,形成一个独立的单元——对象
    • 抽象:是一个不能实例化的类,它定义了子类必须实现的接口,但可能不包含具体实现
  • **继承:**继承是子类自动获取父类的所有非私有属性和方法的过程
  • **多态:**同一种接口可以有多种不同的实现方式
  • 抽象:也是面向对象的一大特征

类和对象出现的先后顺序

  • 站在人的角度

现有对象再有类,现有人这个对象才会衍生出人群这个类

  • 站在代码运行角度

是先有类后有对象,类是对象的模板,先有类才会有对象产生出来


封装

好处


模块化:一个对象的原始文件可以独立地被编写及维护而不影响其他对象,而且对象可以轻易地在系统中反复传递使用。就好像借车给朋友,而车任然能使用一样。

信息隐藏:一个对象有一个公开的接口可供其他对象与之沟通(消息传递),但该对象仍然可以维持自己私有信息及方法,不被外界访问,可提高程序的安全性,保护数据。

封装思想

  • 即类似于ATM机,将插卡口和取款口供用户使用,但是银行卡插入机器之后,并不知道钱是怎么出来的,也不知道银行卡里面的余额是怎么增加或减少的。

  • 高内聚,低耦合思想:开发人员一向追求“高内聚低耦合”思想,高内聚代表一个类中的代码之间的粘合度要高,但是类和类之间的粘合度要尽量低,所以可以通过封装思想来体现“高内聚低耦合”。

八大真言

属性私有(private),get/set公开

private:私有的

get:获得数据

set:给数据设置值

public class Person {
    private String name;  // 属性私有
    
    //无参构造方法
    public Person(){
    
    }

    // getName获取数据name
    public String getName() {
        return name;
    }

    // setName给数据设置值
    public void setName(String name) {
        // 可以在此处添加数据验证或业务逻辑
        if (name != null && !name.isEmpty()) {
            this.name = name;
        } else {
            throw new IllegalArgumentException("Name cannot be null or empty.");
        }
    }
}

测试

package ooday02;

public class encapsulationTest {
    public static void main(String[] args) {
        Person a=new Person();
        a.setName("千羽");
        System.out.println(a.getName());
    }
}//输出:千羽  

快捷键

alt+insert–>getter and setter–>选中要添加的getset方法的属性—->点击ok


**注:**一个完整的封装,必须含有一个无参构造方法


继承(extends)

子承父业,继承家产

Java中只有单继承(可以通过之后学习的接口实现多继承)

继承关系中两个类,一个为子类(派生类)一个为父类 (基类),子类继承父类,使用关键字extends来表示

从某种意义上来说就是“谁是谁的什么 ”的关系

子类会继承父类的所有东西前提是访问权限是public


优势

  1. 实现代码复用:利用已经存在的父类代码,在编写子类时,只要针对其所需的特别属性与行为进行编写即可,可提高程序编写效率
  2. 简化设计过程:先定义好父类,复用这些类进行子类设计,可以简化设计过程,缩短开发周期,同时提高系统性能。

创建一个父类:

package ooday02;
//创建人的类
public class Person {//Person类
    String name;
    int age;
    String address;

    void eat(){
        System.out.println(name+"正在吃饭");
    }
    void  sleep(){
        System.out.println(name+"正在睡觉");
    }
    void savhi(){
        System.out.println("大家好,我叫"+name+"今年"+age+"岁了,家住"+address);

    }
}

创建两个子类

package ooday02;
//创建一个学生的类
public class student extends Person {//继承Person的父类
    String ClassName;
    String stuid;


    void zs(){
        System.out.println("我叫"+name);
    }
    void dz(){
        System.out.println("今年我"+age+"我的家住在"+address);
    }

    student(){

    }
    //student继承了Person父类的name,age,address属性
    student(String name, int age, String address,String ClassName,String stuid){
        super.name=name;
        super.age=age;
        super.address=address;
        this.ClassName=ClassName;
        this.stuid=stuid;
    }
}
package ooday02;
//创建一个老师类,
public class teacher extends Person {//继承Person父类
    double salary;
    String className;

        void xm(){
            System.out.println(name+"正在"+className+"班讲课");
    }
        teacher(){
                    }
//teacher继承了Person父类的name,age,address属性
    teacher(String className,double salary, String name, int age, String address){
           this.className=className;
           this.salary=salary;
           super.name=name;
           super.age=age;
           super.address=address;
        }
}

测试继承类

package ooday02;
//创建人的类
public class ex {
public static void main(String[] args) {
        student xs=new student("李四",22,"成都","js20405","2245689");
        xs.dz();
        xs.zs();
        xs.eat();
        xs.sleep();
        xs.savhi();
    }
}

Object类

Object类是所有类的顶级父类,在Java体系中,所有类 的是直接或间接的继承了Objcet类。Object类中包含了 所有Java类的公共属性和方法,这些属性和方法在任何 类中均可以直接使用。

常用方法:

toString():将调用toString方法的对象转换成字符串

clone():复制

hashCode():返回对象的哈希码

getClass():获取当前对象所属类的信息,返回Class 对象


方法的重写(Overriding)
  • 发生在父子类中,一定是继承关系。方法名相同,参数列表相同-----子类重新了父类的方法

  • 重写方法被调用时,看对象的类型调用方法(new谁就调用谁)


创建一个父类

package ooday02;
//创建人的类
public class Person {//Person类
    String name;
    int age;
    String address;
    void savhi(){
        System.out.println("大家好,我叫"+name+"今年"+age+"岁了,家住"+address);

    }
}

方法重写

package ooday02;
//创建一个学生的类
public class student extends Person {//继承Person的父类
    String ClassName;
    String stuid;

    void savhi(){//方法的重写
        System.out.println("大家好,我叫"+name+"今年"+age+"岁了,家住"+address+"我重写了父类的方法");

    }

    student(){

    }
    //student继承了Person父类的name,age,address属性
    student(String name, int age, String address,String ClassName,
            String stuid){
        super.name=name;
        super.age=age;
        super.address=address;
        this.ClassName=ClassName;
        this.stuid=stuid;
    }
}
package ooday02;
//方法的重写
public class OverrideDemo {
    public static void main(String[] args) {

        student xs=new student("李四",22,"成都","js20405","2245689");
        xs.savhi();//调用student重新之后的
    }
}

super用法

代表父类对象。通过使用super关键字,可以访 问父类的属性或方法,也可以再子列的构造方法中调用父 类的构造方法,以便初始化从父类继承的属性


补充

  • 快捷键:ctrl+H打开关系继承图

  • object

是所有类的父类(超级父类),在java中,所有类都会默认直接或间接地去继承object类。

  • 泛化

从设计角度而言叫泛化,从代码角度而已是继承,泛化即时继承

  • 继承要符合(是)的关系
  • super:继承的是父类的成员变量和普通方法,不包括构造方法,父类的构造方法是被子类通过super来调用的

多态

定义

指不同的对象在调用同一个方法时所呈现的多种不同行为


多态的前提条件

  • 要有继承或者实现的关系
  • 要有方法重写
  • 要有父类引用指向子类对象

**注意:**多态是方法的多态,属性没有多态

package ooday03;

public class Polymorphism {
    int age=2;

    public void eat(){
        System.out.println("多态");
    }
}
package ooday03;

public class Polymorphism01 extends Polymorphism {
   int age=5;
    @Override
    public void eat() {
        System.out.println("1方法的重写,多态");
    }
}
package ooday03;
//多态
public class Polymorphism02 {
    public static void main(String[] args) {
        //从父类引用指向子类对象
        Polymorphism a=new Polymorphism01();
        System.out.println(a.age);//输出2
        a.eat();//输出1方法的重写,多态
    }
}

类型转换

转换成功的条件

  • 引用所指的对象,就是该类型

  • 引用所指的对象,实现了该接口或继承了该类

Animals a=new Dog;//Dog对象可以转换Dog对象,继承的父类animals,接口的swim
Dog a1=(Dog)a;
Dog a2=(swim)a;
Animals b=new Fish;//Dog对象可以转换Fish对象,继承的父类animals,接口的swim
Fish b1=(Dog)b;
Fish b2=(swim)b;

强转之前使用instanceof判断引用所指向的对象类型是否是该类型

if(b instanceof Fish){
Fish b1=(Fish)b;
}

抽象(abstract)


抽象类与抽象方法
  • 抽象类

用 abstract 关键字来修饰一个类时,这个类就叫抽象类

语法格式

访问限定符   abstract class 类名{

}

抽象类不能被直接的实例化,即不能new创建对象,是不完整的

但可以通过子类间接的实例化

也因此抽象类是需要被继承的


  • 抽象方法

用 abstract 关键字来修饰一个方法时,这个方法就叫抽象方法

语法格式

访问修饰符 abstract 返回类型 方法名(形参列表);//抽象方法不能指定主体,只有方法头

凡是有抽象方法的类必须是抽象类,但有抽象类时却不一定要有抽象方法

抽象方法不需要具体实现,因此没有方法体

也因此如果一个类继承了抽象类,则它必须实现(重写)抽象类的所有抽象方法;除非它自己也声明为抽象类则不需要重写抽象方法。

因为一个类继承了抽象类必须实现(重写)抽象类的所有抽象方法,因此抽象方法在定义时不能使用 private、final 和 static 关键字来修饰,这与重写相违背。


package 抽象;
//abstract:表示抽象
public abstract class 抽象类_方法 {//抽象类
            public abstract  void eat();//抽象方法
    /*有抽象方法必须有抽象类,有抽象类不一定有抽象方法*/
    public abstract void go();
    }

package 抽象;

public class 子类 extends 抽象类_方法{//抽像类需要被继承
    //子类必须重写抽象父类中的所有抽象方法
    @Override
    public void eat() {
        System.out.println("必须重写父类的所有抽象方法");
    }
    public void go(){
        System.out.println("重写了父类的抽象方法");
    }
}

package 抽象;

public class 抽象类测试 {
    public static void main(String[] args) {
           子类 a=new 子类();
           a.eat();
           a.go();
    }
}

接口(interface)


是一种引用数据类型


接口的应用

  • 接口是对继承单根性的拓展------实现多继承

  • 接口是一种标准,规范,表述具备某种功能

    • 实现了某接口就是具备某个功能
  • 不能被实例化

  • 接口是需要被实现/继承的,实现类/派生类:必须重写接口中的所有抽象方法

    • 注意:重写接口中的方法时,必须加public(先记住)
  • 接口是一种完全抽象的类,比抽象更为抽象

  • 接口没有类的实现,只有方法的定义(常量、默认方法、静态方法、私有方法)

  • 一个类可以实现多个接口,用逗号分隔。若又继承又实现时,应先继承后实现

  • 接口可以继承接口

package ooday04;
//interface定义关键字,接口都需要有实现类
public interface interFace {
    //接口中的所有定义其实都是默认抽象的public abstract,可不写
    void add();//接口没有类的实现,只有方法的定义
    void add1();
    void add2();
    void add3();
}

测试

package ooday04;
//实现了接口的类,就需要重写接口中的方法
public class interFace01 implements interFace,interFace02{//implements:接口可以实现多继承   implements:实现
    
   //重写接口中的抽象方法时,必须加public
    @Override
    public void add(String name) {

    }

    @Override
    public void add1(String name) {

    }

    @Override
    public void add2(String name) {

    }

    @Override
    public void add3(String name) {

    }
}

实现

package ooday04;
public class 实现 {
    public static void main(String[] args) {
        interFace01 f=new interFace01();
        f.add();
        f.add1();
        f.add2();
        f.add3();
    }
}

类(class)

类概述

类是Java中的蓝图或模板,它定义了对象的结构和行为。类包含了数据成员(属性/变量)和成员方法。类是抽象的,它不直接存储数据,而是用于创建对象。类是Java程序中最小的组成单位。


类与对象

类和对象的定义

类是模板,对象是具体的事物,类是一种抽象的引用数据类型,用于描述事物。即类是对象的抽象,对象是类的实例。

类的构成

属性:在类中(Java.class)中定义的一些成员变量、常量。

方法:main方法,自定义方法。(即成员方法)


类的声明

(1)语法格式:

修饰符  class  类名{

     属性;

    方法;

}

**注意:**修饰符可省略(省略时默认为default)


常用修饰符和关键字

  • Default:默认(没有修饰符)

    • 类、变量或方法没有指定任何访问修饰符时,它们具有默认的访问级别,也称为包级私有。这意味着它们只对同一包内的类可见,对包外的类不可见
  • public:(公有的)

    • 公共访问权限,使用public关键字声明的类、接口、变量或方法可以被任何其他类访问,无论是在同一个包内还是不在同一个包内
  • Protected:保护的

    • 受保护访问权限,使用protected关键字声明的类、变量或方法可以被同一包内的任何类以及不同包中的子类访问
  • Private:私有得

    • 私有访问权限,使用private关键字声明的类、变量或方法只能在定义它们的类内部访问,对同一包内的其他类或不同包的子类都不可见
  • abstract:(抽象的)----关键字

    • 用于声明抽象类或抽象方法
  • final:(终极的)-----关键字

    • 当应用于类时,表示类不能被继承,但可以继承别的类。即不能成为父类,但可以当子类

    • 当应用于方法时,表示方法不能被子类重写

    • 当应用于变量时,表示变量一旦赋值后不能改变

  • extends----关键字

    • 指明该类继承的父类
  • implements----关键字

    • 指明该类所要实现的接口

final关键字

通过使用final,可以确保代码的稳定性和安全性,防止意外的修改,并帮助编译器进行优化

  • 当应用于类时,表示类不能被继承,但可以继承别的类。即不能成为父类,但可以当子类

  • 当应用于方法时,表示方法不能被子类重写

  • 当应用于变量时,表示变量一旦赋值后不能改变,

  • 在讨论异常处理时,final 可用于声明一个不能被覆盖的finally块,确保在程序的任何情况下都会执行某些清理代码。

  • 通常用于声明常量,比如PI、E等,可以提高代码的可读性和可维护性。


final,finally、finalize的区别

final:可以修饰类(类不可以被继承)、方法(方法不可 以被重写、修饰变量(表示常量,一旦赋值,就不可以改变

finally:用于异常处理,表示最终一定会执行的,只能用在 try/catch语句中

finalize:用于资源回收(一般不推荐使用)


创建与初始化对象

使用new关键字创建对象:

使用new关键字创建的时候,除了分配内存空间之外, 还会给创建好的对象进行默认初始化,以及对类中构造器 (构造方法)的调用


类的构造方法

在当前代码中没有写任何方法,但一样可以通过new关键字进行实例化操作并且执行代码,原因是因为在jdk底层就会自动生成一个默认的无参构造方法。


构造方法的作用

进行初始化操作,使用new关键字的本质就是调用构造方法


语法规则

方法名和类名相同

没有返回值(即使是void也不行)

 构造方法的格式:[<访问权限>] <类名> ([<参数列表>]){
       this.;//构造方法赋值
}


  • 是一种特殊的方法,用来初始化值。

  • 和类的名字完全相同

  • 没有返回类型

  • 若不提供构造方法,则系统默认无参构造方法


有参构造

注意

如果自己定义了一个有参构造方法,则必须显示定义一个无参构造方法。

package ooday01;
//类
public class Student {
    //属性  字段
    String name;
    int age;
    String className;
    String stuId;
    //方法-----描述对象的行为
    void  study(){
        System.out.print("大家好,我叫"+name);
    }
    void sayHi(){
        System.out.println("今年"+age+"岁"+
                "所在班级"+className+"学号为"+stuId);}

    //有参构造    生成构造器快捷键:alt+insert
   Student (String name1,int age1,String className1,String stuId1){
        this.name=name1;
        this.age=age1;
        this.className=className1;
        this.stuId=stuId1;
    }
}
package ooday01;
//有参构造
public class ConsDemo01 {
    public static void main(String[] args) {
        //实例化赋值一路完成
        Student yc=new Student("zl",23, "hjk","dsdsd");
       //调用
        yc.study();
        yc.sayHi();
    }
}

无参构造
package ooday01;
//类
public class Student {
    //属性  字段
    String name;
    int age;
    String className;
    String stuId;
    //方法-----描述对象的行为
    void  study(){
        System.out.print("大家好,我叫"+name);
    }
    void sayHi(){
        System.out.println("今年"+age+"岁"+
                "所在班级"+className+"学号为"+stuId);}


    /*构造方法     无参构造:类名相同,无参数
    * 一个类即使什么都不写,它其实在底层也会存在一个方法*/
    Student(){

    }
 }
package ooday01;
//构造方法
public class ConsDemo {
    public static void main(String[] args) {

        //无参构造
        //实例化对象
        Student wc=new Student();
        //赋值
        wc.name="张三";
        wc.age=24;
        wc.className="js2045";
        //调用
        wc.study();
        wc.sayHi();

    }
}

对象的使用
  1. 对象名.属性访问对象的属性,只有属性访问权限是非 私有的才能调用
  2. 对象名.方法名调用对象的方法

实例化一个类


  • 对象的初始化

(1) 使用new关键字来创建对象(要告诉jdk我接下来要使用某个类)。

(2) New关键字的作用:

·分配空间(开辟地址)

·进行默认初始化操作

·调用构造器(构造方法)

(3) 初始化对象:使用new关键字创建完对象之后,由于对象有很多很多个,要找到具体的某一个来帮我做事。这个过程就叫做初始化对象。

语法:

类 引用类型变量=new 类名();
语义:声明了一个类的引用类型变量,指向了一个对象
  • 对象的赋值和使用

(1)对象的赋值:

对象名.属性名=属性值

(2)对象的使用:

对象名.属性名/方法名

package ooday01;
//测试类/实例化类
public class StudentTest {
    public static void main(String[] args) {
        //创建一个学生对象
        Student zg = new Student();//zg对象就是一个Student类的具体实例
        /*注意:使用new关键字的时候不仅是分配了空间,还对创建好的对象进行了默认的初始化*/
        //访问成员变量,即赋值
        zg.name = "张光";
        zg.age = 22;
        zg.className = "js20405";
        zg.stuId = "111110";

        //调用方法
        zg.study();
        zg.sayHi();
        zg.playWith("ll");
    }
}/*输出:
大家好,我叫张光今年22岁所在班级js20405学号为111110
张光正在和ll一起玩*/


创建对象内存分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


内存管理
堆:new出来的对象(包括实例变量,数组元素,方法地址)
栈:局部变量(包括方法的参数)
方法区:class字节码文件(包括所有方法,静态变量)


使用

1.使用到哪个类,就会将那个类的.class加载到方法区中
2.调用方法时,方法就会入栈,方法执行完后,方法就会出栈
3.new出来的对象存储在堆中,引用里面装的是对象的地址


变量的分类

  • 类变量(静态变量):在类中定义的变量,并且需要使用static关 键字进行修饰,也称静态变量,存储在方法区中,只有一份由类名访问
  • 实例变量:在类中定义的变量。没有static,属于对象,存储在堆中,有几个对象就有几份对象
  • 局部变量:在方法中定义的变量。局部变量的作用范围有限,只在相应的方法、构造器、循环或块的内部有效,超出范围,这些变量无效。
  • 成员变量(实例变量):在类定义中声明,用于存储对象的状态信息。由类变量与实例变量组成。
  • 常量(常量变量):常量是不可修改的变量,通常用 final 关键字声明。如果同时使用 finalstatic,则称为静态常量或类常量,如 public static final double PI = 3.14159;

引用类型数组

引用类型数组的元素赋值时,需要new个对象

访问引用类型数组的元素的属性/行为时,需要打点访问

package 引用类型数组;
public class demo {
    public static void main(String[] args) {
        Dog[] a = new Dog[2];
        a[0]=new Dog("小黑", "black");
        a[1]=new Dog("小白", "white");
        System.out.println(a[0].name);//输出第一个a的名字
        System.out.println(a[1].color);//输出第二个a的颜色
        a[0].eat();//输出第一个a的eat方法
        a[1].color= "red";//修改第2个a的颜色为red
        System.out.println(a[1].color);//输出第2个a的颜色
    }


    public static class   Dog{
        String name;
        String color;

        Dog(){

        }
        Dog(String name,String color){
            this.name=name;
            this.color = color;
        }
        void eat(){
            System.out.println("eat");
        }
    }
}

静态

静态变量

  • 由static修饰
  • 属于类,存储在方法区中,只有一份
  • 常常通过类名点来访问
  • 何时用:对象所共享的数据
public class StaticVar {
    int a; //实例变量
    static int b; //静态变量
    StaticVar(){
        a++;s
        b++;
    }
    void show(){
        System.out.println("a="+a+",b="+b);
    }
}

public class StaticDemo {
    public static void main(String[] args) {
        StaticVar o1 = new StaticVar();
        o1.show();
        StaticVar o2 = new StaticVar();
        o2.show();
        StaticVar o3 = new StaticVar();
        o3.show();
        System.out.println(StaticVar.b); //常常通过类名点来访问
    }
}

静态方法

  • 由static修饰
  • 属于类,存储在方法区中,只有一份
  • 常常通过类名点来访问
  • 静态方法中没有隐式this传递,所以静态方法中不能直接访问实例成员(实例变量/实例方法)
  • 何时用:方法的操作与对象无关(不需要访问对象的属性/行为)
public class StaticMethod {
    int a; //实例变量(对象来访问)--------------属于对象的
    static int b; //静态变量(类名来访问)-------属于类的

    //静态方法何时用:方法的操作与对象无关(不需要访问对象的属性/行为)

    //在say()中需要访问对象的属性a,所以认为say的操作与对象有关,不适合设计为静态方法
    void say(){
        System.out.println(a);
    }
    //在plus()中不需要访问对象的属性/行为,所以认为plus的操作与对象无关,可以设计为静态方法
    static int plus(int num1,int num2){
        int num = num1+num2;
        return num;
    }

    void show(){ //有隐式this
        System.out.println(this.a);
        System.out.println(StaticMethod.b);
    }
    static void test(){ //没有隐式this
        //静态方法中没有隐式this传递
        //没有this就意味着没有对象
        //而实例变量a必须通过对象来访问
        //所以如下语句发生编译错误
        //System.out.println(a); //编译错误,静态方法中不能直接访问实例成员
        System.out.println(StaticMethod.b);
    }
}

public class StaticDemo {
    public static void main(String[] args) {
        StaticMethod.test(); //常常通过类名点来访问
    }
}

静态块

  • 由static修饰
  • 属于类,在类被加载期间自动执行,一个类只被加载一次,所以静态块也只执行一次
  • 何时用:初始化/加载静态资源/静态变量
public class StaticBlock {
    static{
        System.out.println("静态块");
    }
    StaticBlock(){
        System.out.println("构造方法");
    }
}

public class StaticDemo {
    public static void main(String[] args) {
        StaticBlock o4 = new StaticBlock(); //加载类时自动执行静态块
        StaticBlock o5 = new StaticBlock();
        StaticBlock o6 = new StaticBlock();
    }
}

Static final常量

  • 必须声明同时初始化
  • 常常通过类名点来访问,不能被改变
  • 建议:常量名所有字母都大写,多个单词之间用_分隔
  • 编译器在编译时,会将常量直接替换为具体的数,效率高
  • 何时用:在程序运行过程中数据永远不变,并且经常使用
public class StaticFinalDemo {
    public static void main(String[] args) {
        System.out.println(Loo.PI); //常常通过类名点来访问
        //Loo.PI = 3.1415926; //编译错误,常量不能被改变

        //1)加载Loo.class到方法区中
        //2)静态变量num一并存储到方法区中
        //3)到方法区中获取num的值并输出
        System.out.println(Loo.num);

        //编译器在编译时会将常量直接替换为具体的数,效率高
        //相当于System.out.println(5);
        System.out.println(Loo.COUNT);
    }
}

class Loo{
    public static int num = 5; //静态变量
    public static final int COUNT = 5; //常量(静态常量)

    public static final double PI = 3.14159;
    //public static final int NUM; //编译错误,常量必须声明同时初始化
}

枚举

  • 是一种引用数据类型
  • 特点:枚举类型的对象数目是固定的,常常用于定义一组常量
  • 枚举的构造方法都是私有的
  • 所有枚举都继承自Enum类,其中提供了一组方法供我们使用
//简单版:
package ooday05;
/**
 * 季节枚举
 */
public enum Seasons {
    //public static final Seasons SPRING = new Seasons();
    //public static final Seasons SUMMER = new Seasons();
    //public static final Seasons AUTUMN = new Seasons();
    //public static final Seasons WINTER = new Seasons();
    SPRING,SUMMER,AUTUMN,WINTER //表示Seasons的固定的4个对象,都是常量
}

package ooday05;
/**
 * 枚举的测试类
 */
public class EnumTest {
    public static void main(String[] args) {
        Seasons[] seasons = Seasons.values(); //获取所有枚举对象
        for(int i=0;i<seasons.length;i++){
            System.out.println(seasons[i]);
        }
        /*
        Seasons s = Seasons.WINTER; //获取WINTER对象
        switch(s){
            case SPRING:
                System.out.println("春天到了...");
                break;
            case SUMMER:
                System.out.println("夏天到了...");
                break;
            case AUTUMN:
                System.out.println("秋天到了...");
                break;
            case WINTER:
                System.out.println("冬天到了...");
        }
         */
    }
}
```java
 //复杂版:
 package ooday05_vis;
 /**
  * 季节枚举
  */
 public enum Seasons {
     SPRING("春天","暖和"),
     SUMMER("夏天","热"),
     AUTUMN("秋天","凉爽"),
     WINTER("冬天","冷"); //创建季节对象(调用有参构造方法)
     private String seasonName;
     private String seasonDesc;
     Seasons(String seasonName, String seasonDesc) { //构造方法默认为private的(只能私有)
         this.seasonName = seasonName;
         this.seasonDesc = seasonDesc;
     }
 
     public String getSeasonName() {
         return seasonName;
     }
     public void setSeasonName(String seasonName) {
         this.seasonName = seasonName;
     }
     public String getSeasonDesc() {
         return seasonDesc;
     }
     public void setSeasonDesc(String seasonDesc) {
         this.seasonDesc = seasonDesc;
     }
 }
 
 package ooday05_vis;
 
 /**
  * 枚举的演示
  */
 public class EnumTest {
     public static void main(String[] args) {
         Seasons s = Seasons.WINTER;
         System.out.println(s.getSeasonName()+","+s.getSeasonDesc());
 
         Seasons[] seasons = Seasons.values();
         for(int i=0;i<seasons.length;i++){
             System.out.println(seasons[i]);
             System.out.println(seasons[i].getSeasonName());
             System.out.println(seasons[i].getSeasonDesc());
         }
     }
 }
 ```
ay05_vis;
 /**
  * 季节枚举
  */
 public enum Seasons {
     SPRING("春天","暖和"),
     SUMMER("夏天","热"),
     AUTUMN("秋天","凉爽"),
     WINTER("冬天","冷"); //创建季节对象(调用有参构造方法)
     private String seasonName;
     private String seasonDesc;
     Seasons(String seasonName, String seasonDesc) { //构造方法默认为private的(只能私有)
         this.seasonName = seasonName;
         this.seasonDesc = seasonDesc;
     }
 
     public String getSeasonName() {
         return seasonName;
     }
     public void setSeasonName(String seasonName) {
         this.seasonName = seasonName;
     }
     public String getSeasonDesc() {
         return seasonDesc;
     }
     public void setSeasonDesc(String seasonDesc) {
         this.seasonDesc = seasonDesc;
     }
 }
 
 package ooday05_vis;
 
 /**
  * 枚举的演示
  */
 public class EnumTest {
     public static void main(String[] args) {
         Seasons s = Seasons.WINTER;
         System.out.println(s.getSeasonName()+","+s.getSeasonDesc());
 
         Seasons[] seasons = Seasons.values();
         for(int i=0;i<seasons.length;i++){
             System.out.println(seasons[i]);
             System.out.println(seasons[i].getSeasonName());
             System.out.println(seasons[i].getSeasonDesc());
         }
     }
 }
 ```
  • 29
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值