[03] 类的结构和创建对象

1、类的结构和定义

先回顾一下,类的基本概念:

  • 类定义了对象共同的属性和行为(即方法)
  • 具体的某个对象需要通过类来进行申明

那么显而易见地,类中应该包含的东西就有,属性、方法,另外,既然对象要通过类来声明,那么类中必须要有一个类似生产机器的东西来生成对象,这个类似生产机器的东西叫做构造函数。另外,类还可有内部类和块,这两种使用较少。

所以,类的结构内容就是:

  • 属性(对象数据的描述)
  • 方法(对象的行为)
  • 构造函数(用于生产对象,也叫做实例化对象)
  • 内部类(在类体中申明的类)
  • (分为静态块、实例块)
  1. public class Person {
  2. //属性
  3. String name;
  4. int age;
  5. //方法
  6. public void eat() {
  7. System.out.println("吃东西");
  8. }
  9. public void run() {
  10. System.out.println("跑起来");
  11. }
  12. //构造方法
  13. public Person() {
  14. }
  15. //块
  16. {
  17. System.out.println("我是实例块");
  18. }
  19. static {
  20. System.out.println("我是静态块");
  21. }
  22. //内部类
  23. class InnerClass{
  24. }
  25. }

1.1 类的申明

  1. 【访问权限修饰符】【修饰符】class 类名 {
  2. 类体
  3. }
  4. //【】中的内容表示可选项
  5. e.g.
  6. public class Person {
  7. ...
  8. }
  • 类的命名规范:首字母大写,之后的单词首字母才大写,其余小写
  • 访问权限修饰符:default、private、protected、public(default即什么都不写)
  • 修饰符:final、synchronized、abstract
  • 访问权限修饰符和修饰符在之后说明,本章不做说明

1.2 属性的申明

  1. 【访问权限修饰符】【修饰符】数据类型 属性名【=初值】;
  2. //【】中的内容表示可选项
  3. e.g.
  4. private String name;
  5. private double salary;
  6. private static int count = 0;
  • 属性的命名规则:小写,多个单词则后面的单词首字母大写
  • 注意:属性又称为成员变量,是声明在类中的变量,方法体中声明的变量称为局部变量或临时变量

1.3 方法

1.3.1 方法的申明

  1. 【访问权限修饰符】【修饰符】返回值数据类型 方法名(形式参数列表) {
  2. 执行语句;
  3. return 返回值;
  4. }
  5. //【】中的内容表示可选项
  6. e.g.
  7. public String eat(String food){
  8. return "吃" + food;
  9. }
  10. public void eat(){
  11. System.out.println("吃东西");
  12. }
  • 方法命名规范:小写,多个单词则后面的单词首字母大写
  • 返回值类型必须填写,如果没有类型也需要填写void(如果是void则不需要return语句)

1.3.2 方法中的部分概念解释

方法,其实就是定义在类中具有特定功能的一段独立小程序,更多时候我们称之为函数。

形式参数,就是一个变量,用来传递给方法进行使用,就像 public String eat(String food){ ... },某个人要执行吃的行为,那得递给他食物他才能行动呀,所以这里的食物,就是吃这个方法的参数。

返回值,即如果你关心并希望得到这个方法的执行结果,那么需要规定返回值的数据类型,再使用return语句把结果告诉你。如果你只是进行一些操作,不关心最终的结果,就像你只想执行吃饭的操作,你不关心最终吃没吃饱,那么就意味着没有返回值,那么返回值数据类型就填写void,也没有return语句。

1.3.3 方法的特点

  • 定义方法可以将功能代码进行封装
  • 方法可以复用
  • 方法只有被调用时才会执行
  • 方法中可以调用其它方法,但是不可能在方法内部定义方法

1.3.4 方法重载

如果在一个类中,需要实现两个整数求和,两个浮点数求和,这两个方法如何定义?

1、定义两个方法,分别命名为addInt、addDouble

2、定义一个方法,叫add,但形参数据类型不同

显然,使用后者更为适宜,所以在Java中,如果有多个同名但是不同参数的方法,我们称之为“方法重载”,编译器会根据调用时传递的实际参数自动判断具体调用的是哪个重载方法。

  1. e.g.
  2. int add(int x, int y){...}
  3. float add(float x, float y){...}
  4. double add(double x, double y){...}

所谓的不同参数,是指参数的:

  • 数量不同
  • 类型不同
  • 顺序不同

值得一提的是,方法重载跟方法的返回值类型没有任何关系,也就是说,如果只是返回值不同的方法,不能构成重载。

  1. //错误的方法重载
  2. void fun(int x){...}
  3. int fun(int x){...}

1.4 构造方法

  1. 【访问权限修饰符】类名(形式参数列表){
  2. 方法体
  3. }
  4. //【】中的内容表示可选项
  • 构造方法的名称必须和类名相同
  • 构造方法也有方法重载
  • 构造方法中也可以编写复杂程序,但是一般只用于定义属性,即初始化对象属性

那么问题来了:

构造方法是用来声明类的,那么为什么我们有时候不写构造方法,依然可以进行实例化?

那么答案来了:

任何类都有一个默认的无参的构造方法,只有在你自定义了某个构造方法后,这个默认的无参构造方法才会失效。


2、创建对象

2.1 实例化对象

使用new调用构造方法,创建类的一个对象:

  1. //调用无参数的构造方法
  2. 类名 对象名 = new 该类的构造方法();
  3. e.g. Book javaBook = new Book();
  4. //调用有参数的构造方法
  5. 类名 对象名 = new 该类的构造方法(参数1, 参数2...);
  6. e.g. Book javaBook = new Book("西游记");

使用对象,可以使用 “.” 进行以下操作:

  • 访问类的属性:对象名.属性
  • 调用类的方法:对象名.方法名()
  1. e.g.
  2. javaBook.name = "东游记";
  3. javaBook.borrow();

2.2 实例化对象的过程

假设存在一个类Person,创建对象语句如下:

  1. Person zhangsan = new Person();

将上面的语句分为两个步骤:

  1. Person zhangsan;
  2. zhangsan = new Person();

即,实例化一个对象后,其实有两个实体:

  • 对象引用变量,在栈空间,即zhangsan,称之为引用,或句柄,存放的是对象的虚地址
  • 对象本身,即使用new Person()在堆空间里创建的实体,将对象的属性值存储在堆里
  • 可以使用引用变量操作对象的属性和方法

意思类似于旅馆的房间和钥匙:

  • 当你使用new时,就相当于在旅馆前台说你要开个房间,那么前台会给你一把钥匙,就是这里的引用变量,如上例的zhangsan
  • 钥匙指向房间,所以有了钥匙你就能找到房间,才能对房间进行布置
  1. public class Room {
  2. private String bed;
  3. private String lamp;
  4. public Room(String bed, String lamp) {
  5. this.bed = bed;
  6. this.lamp = lamp;
  7. }
  8. public String getBed() {
  9. return bed;
  10. }
  11. public void setBed(String bed) {
  12. this.bed = bed;
  13. }
  14. public String getLamp() {
  15. return lamp;
  16. }
  17. public void setLamp(String lamp) {
  18. this.lamp = lamp;
  19. }
  20. public static void main(String[] args) {
  21. Room room1 = new Room("单人大床", "小灯");
  22. Room room2 = new Room("双人大床", "大灯");
  23. }
  24. }

如上例:

1、把Room类的字节码加载到内存

2、根据Room类的申明,把属性bed、lamp初始化到内存堆,并赋默认值,String的默认值为null

3、根据代码,调用两个参数的构造方法,把"单人大床"和"小灯"分别赋值给bed和lamp

4、在栈中创建一个变量room1,用来引用堆中的对象,room1的值是一个16进制的数,表示一个虚地址

5、重复2-4创建room2,room2和room1是不同的引用,指向不同的具体对象


3、块与内部类

块在类中申明,类似一个没有方法申明的方法体,分实例块和静态块。

3.1 块

3.1.1 实例块

顾名思义,属于某个具体的对象,所以会在每次调用构造方法之前自动调用

  1. {
  2. //任何符合语法的Java代码
  3. }

3.1.2 静态块

在类加载时被调用一次,仅一次,与是否创建对象无关

  1. static {
  2. //任何符合语法的Java代码
  3. }

3.2 内部类

将一个类的定义放到另一个类中,就是内部类。

  1. public class Outer{
  2. private int x;
  3. class Inner{
  4. public test(){
  5. x++;
  6. }
  7. }
  8. }

内部类对于初学者使用很少,这里不再详细阐述了,可以参考:

时间: 2024-10-01 04:03:23

[03] 类的结构和创建对象的相关文章

C#类和结构的关系

主要联系:类和结构都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法.类定义了每个类对象(实例)可以包含什么数据和功能.例如,如果一个类表示一个顾客,就可以定义字段CustomerID.FirstName.LastName和Address,包含该顾客的信息.还可以定义处理存储在这些字段中的数据的功能.接着就可以实例化这个类的对象,以表示某个顾客,并为这个实例设置这些字段,使用其功能. class PhoneCustomer { public const string DayOf

【JavaScript】获取未知类的结构

目录结构: contents structure [-] 为什么需要获取类的结构 关于JavaScript中的类 定义类的方法 第一种 第二种 DEMO HTML页面 date文件 注意事项 参考文章 为什么需要获取类结构的代码 笔者认为主要是方便,如果一个项目很大或是引用了其它地方的js文件,如果顺着src文件查找会很麻烦.为了对代码理解的更好,还需要对javaScript的类有所了解,更多情况读者可以参考JavaScript定义类的三种方法. 关于javascript中对类的简介 其实Jav

类和结构

类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法.类定义了类的每个对象(称为实例)可以包含什么数据和功能. 结构与类的区别是它们在内存中的存储方式.访问方式(类是存储在堆heap)上的引用类型,而结构是存储在栈(stack上的值类型)和它们的一些特征(如结构不支持继承).较小的数据类型使用结构可提高性能.但在语法上,结构与类非常相似,主要的区别是使用关键字siuct代替dass来声明结构. 类 类中的数据和函数称为类的成员.Microsoft的正式术语对数据成员

类和结构(二)

二.匿名类型 var关键字用于表示隐式类型化得变量.var和new关键字一起使用时,可以创建匿名类型. 匿名类型只是一个继承自Object且没有名称的类. var caption = new {FirstName = "John",LastName="Doe"}; 这会生成一个包含FirstName,LastName属性的对象. 创建另一个对象: var doctor = new {FirstName = "James",LastName=&qu

类和结构(一)

类和结构实际上都是创建对象(实例)的模版,每个对象都包含数据,并提供了处理和访问数据的方法. 类定义了类的每个对象可以包含什么数据和功能. class PhoneCus { public const string DaySend = "Mon"; public int CusId=; } 结构与类的区别是它们在内存中的存储方式,访问方式和它们的一些特性(稍后详细介绍它们的区别). 较小的数据类型使用结构可提高性能,在语法上,比较类似,主要区别是使用关键字struct代替class来声明

UNITY3D c#脚本中处理类与结构体的区别

1.在C#中结构体类型定义时,成员是不能初始化的,这样就导致了,定义结构体变量时,变量的所有成员都要自己赋值初始化.但对于类,在定义类时,就可以初始化其中的成员变量,所以在定义对象时,对象本身就已经有了初始值,你可以自己在重新给个别变量赋值.(注意在C++中,类的定义中是不能初始化的,初始化要放在构造函数中) 2.结构体变量 和类对象 进行值传递时,结构体变量进行的就是值传递,而类对象进行的是引用传递,或者说传递的是指针,这样在函数中改变参数值,结构体对象的值是不变的,而类对象的值是变化了. 下

进击的雨燕-------------类和结构体

类和结构体是人们构建代码所用的一种通用且灵活的构造体.我们可以使用完全相同的语法规则来为类和结构体定义属性(常量.变量)和添加方法,从而扩展类和结构体的功能. 与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意通常一个类的实例被称为对象.然而在 Swift 中,类和结构体的关系要比在其他语言中更加的密切,本章中所讨论的大部分功能都可以用在类和结构体上.因此,我

C#:类和结构的区别

第一.引用类型和值类型 类属于引用类型,而结构属于值类型. 结构在赋值时进行复制. 将结构赋值给新变量时,将复制所有数据,并且对新副本所做的任何修改不会更改原始副本的数据. 第二.继承性 类可以继承类或者实现接口,而结构只能实现接口,不能继承结构. 第三.实例化 类的实例化需要使用new关键字,但是结构的实例化则可以不使用new关键字. 第四.构造函数 类可以显式地包含无参的构造函数,但是结构却不可以显式地包含无参构造函数,只可以定义带有参数的构造函数. 第五.初始化实例字段 类可以在类的定义中

【Swift】学习笔记(八)——类和结构体

1.类和结构体的定义 <pre name="code" class="html">struct Resolution { var width = 0 var height = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? //值为可选String类型的name } 类:keyw