当前位置: 首页 > article >正文

类和对象(1)

简单认识类

类是用代码的形式来对一个实体(对象)来进行描述的。

主要用代码描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成计算机就可以识别类其中的代码从而描述对象。

类的定义格式 

在java中定义类时需要用到class关键字,具体语法如下

​
// 创建类
class ClassName{  
    field;       //成员变量 :成员变量可以不赋值,不赋值时它的默认值为基础值。
    method;      //  成员方法
}

​

 class为定义类的关键字,ClassName为类的名字,{}中为类的主体。

class WashMachine{
    public String brand;   // 品牌
    public String type;    // 型号
    public double weight;  // 重量
    public double length;  // 长
    public double width;  // 宽
    public double height;  // 高
    public String color;   // 颜色
    
    public void washClothes(){   // 洗衣服
        System.out.println("洗衣功能");
   }
    
    public void dryClothes(){    // 脱水
        System.out.println("脱水功能");
   }
    
    public void setTime(){       // 定时
        System.out.println("定时功能");
   }
}

 采用Java语言将洗衣机类在计算机中定义完成,经过javac编译之后形成.class文件,在JVM的基础上计算机就可以识别了。

注意事项

类名注意采用大驼峰定义

成员前写法统一为public,后面会详细解释

此处写的方法不带 static 关键字. 后面会详细解释

 注意事项:

1. 一般一个文件当中只定义一个类(并不代表着一个文件只能定义一个类,它能定义多个类,只是一个文件一个类便于我们去操作,以后基本都是一个文件一个类,这样更简便)

2. main方法所在的类一般要使用public修饰( 并不代表main方法所在的类一定要用public修饰,其类也可以不用public修饰,但一般情况我们还是用public修饰,只是需要知道main所在类也可以不用public修饰这个点而已

3. public修饰的类必须要和文件名相同

4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改(给同学演示)。

类的实例化

 定义了一个类,就相当于在计算机中定义了一种新的类型。与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:PetDog类和Student类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。

自定义类型都是引用类型,创建的变量为引用变量。 

用定义好的类创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。

注意事项

new 关键字用于创建一个对象的实例.

使用 . 来访问对象中的成员变量和成员方法.

同一个类可以创建多个实例.  

用类创建的对象其中的成员变量分布在堆区,成员方法存储在方法区(使用该方法时会在栈区分配空间)

 类和对象的说明

1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.

2. 类是一种自定义的类型,可以用来定义变量.

3. 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量

4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

 

this引用 

对于一个类去创建多个对象,每个对象都用了类中的成员方法,那么该怎么确定其中的每个方法能对应该对应的对象。这时就出现了this引用。

其实对于类中的普通成员方法,第一个参数其实是该类的类型创建的引用变量this,只是它被隐藏了。对于静态成员方法(类方法)不含this。

对于普通成员方法中的成员变量,前面也自带this.,只是也被隐藏了 。

如下,为正常情况下的,this都被隐藏了

   

这才是this没被隐藏的真正的情况: 

这里还出现了一个问题,当形参名和成员变量名字相同怎么办。 

因为形参是局部变量,在Java中局部变量和全局变量名字相同时,优先选择局部变量。

所以此时就是单纯局部变量给局部变量赋值,不影响成员变量,所以导致结果错误。

​
public class Date {
    public int year;
    public int month;
    public int day;

    public void setDate(int year,int month,int day) {
        year = year;
        month = month ;
        day = day;
    }

    public void print() {
        System.out.println("year: "+year + " month : " +month +" day: "+day);
    }

    public static void main(String[] args) {
   
        Date date2 = new Date();
        date2.setDate(1989,11,11);
        date2.print();

        //此时单纯局部变量给局部变量赋值,成员变量没变依旧是基础值
    }


}

​

结果如下,显示错误。 

 

如果要正确的结果我们应该这样写代码。

​

public class Date {
    public int year;
    public int month;
    public int day;

    public void setDate(int year,int month,int day) {
        this.year = year;
        this.month = month ;
        this.day = day;
    }

    public void print() {
        System.out.println("year: "+year + " month : " +month +" day: "+day);
    }

    public static void main(String[] args) {
   
        Date date2 = new Date();
        date2.setDate(1989,11,11);
        date2.print();

        //此时局部变量和成员变量名字相同,但在year,month,day前面都加了this.,
所以在this后面的这三个变量被识别为成员变量,从而达到正常想要的效果
    }


}

​

​

​

所以我们得出一个结论,成员方法中的成员变量我们都要在前面加个this.即使不加this也是对的,我们也要加它,这样的写法能使其代码更加严谨。

对象的构造及初始化

 初始化分为三种:默认初始化,就地初始化,通过构造方法进行的初始化

默认初始化

 就是创建对象后不进行赋值,它们的值直接为其默认的基础值。

就地初始化 

 在声明成员变量时,就直接给出了初始值。

public class Date {
    public int year = 1900;
    public int month = 1;
    public int day = 1;
 
    public Date(){
   }
 
    public Date(int year, int month, int day) {
   }
 
    public static void main(String[] args) {
        Date d1 = new Date(2021,6,9);
        Date d2 = new Date();
   }
}

构造方法

构造方法一般都是对普通成员变量进行初始化,初始化的是与对象相关的实例。一般不对静态成员变量初始化。

对象的产生需要两个条件

1. 为对象分配内存

2.调用合适的构造方法 

构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,没有返回值,void都不能填。在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。 

执行构造方法的时候是在创建对象的同时执行的

 在给对象分配好内存的同时执行了Date构造方法,然后就创建好了对象。所以说整个对象的构造方法只能调用一次,就是在创建的同时调用的构造方法。

public class Date {
    public int year;
    public int month;
    public int day;
 
    // 构造方法:
    // 名字与类名相同,没有返回值类型,设置为void也不行
    // 一般情况下使用public修饰
    // 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
    public Date(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int,int,int)方法被调用了");
   }
 
    public void printDate(){
        System.out.println(year + "-" + month + "-" + day);
   }
 
    public static void main(String[] args) {
        // 此处创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021,6,9);   // 输出Date(int,int,int)方法被调用了
        d.printDate();    // 2021-6-9
   }
}

 注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。

特性:

1. 名字必须与类名相同

2. 没有返回值类型,设置为void也不行

3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)

4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)  

 

 如果用户没有定义构造方法,编译器会生成一份默认的构造方法,该默认构造方法一定是无参的,方法内部不含任何代码,只有一个空语句。

注意:一旦用户定义了一个构造方法,编译器则不再生成默认的。

 如果有多个构造方法(重载),此时可以使用this的另一个功能。(可以在一个构造方法中通过this使用另一个构造方法)

注意正常情况下一个构造方法内部不能使用另一个构造方法,但通过this我们可以实现该功能。

public class Date {
    public int year;
    public int month;
    public int day;
    
    // 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
    // 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
    // 但是this(1900,1,1);必须是构造方法中第一条语句
    public Date(){
        //System.out.println(year);   注释取消掉,编译会失败
        this(1900, 1, 1);
        
        //this.year = 1900;
        //this.month = 1;
        //this.day = 1;
   }
 
    // 带有三个参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
   }
}

注意this该功能要使用必须在构造方法第一条语句上才能使用

还需注意其不能陷入死循环,如自引用和以下代码,其都会形成一个环从而陷入死循环,系统报错。

绝大多数情况下构造方法使用public来修饰,特殊场景下会被private修饰(后序讲单例模式时会遇到)  


http://www.kler.cn/a/273101.html

相关文章:

  • Docker-安装
  • 我们来学mysql -- 同时使用 AND 和 OR 查询错误(填坑篇)
  • 哔哩哔哩车机版2.7.0|专为司机打造的车机版B站,内容丰富,功能齐全
  • 防重方案-订单防重方案笔记
  • MQTT自动发送消息工具(自动化测试MQTT)
  • 人脑与机器连接:神经科技的伦理边界探讨
  • Centos8安装wdCP
  • MATLAB中如何导出EXE或DLL
  • 缺失的数字(c++题解)
  • 【python开发】并发编程(上)
  • 凝思操作系统离线安装mysql和node
  • python 调用redis创建查询key
  • YOLOv9改进策略:注意力机制 | 用于微小目标检测的上下文增强和特征细化网络ContextAggregation,助力小目标检测,暴力涨点
  • SWUST OJ 961: 进制转换问题
  • 网络管理基础
  • 系统学习Python——装饰器:“私有“和“公有“属性案例-[隐式运行的运算符重载方法无法在Python3.X下委托]
  • 基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的夜间车辆检测系统(深度学习代码+UI界面+训练数据集)
  • 【Redis内存数据库】NoSQL的特点和应用场景
  • 智慧公厕对于智慧城市管理的意义
  • unity3d Animal Controller的Animal组件中General基础部分理解
  • JS原型和原型链的理解
  • 面试经典-基于开放地址手写hashmap
  • Elasticsearch使用Kibana进行基础操作
  • 基于springboot创建mybatis
  • 深度剖析:数字经济下人工智能水平的新测算模型数据集
  • 如何确保面试流程标准化操作,避免人为因素影响**