目录
1. 类和对象的定义,关系
1.1 类和对象的定义
总所周知,Java是一门面向对象的语言,面向对象是解决问题的一种思想,主要依靠对象之间的交互来完成一件事情。所以说,类和对象,在Java语言中有着至关重要的地位。
首先,类它是用来对对象的描述,描述着对象的外观,特点功能和属性等,而对象,就是我们通过类实例化出来的。
举个例子:现在你有一斤排骨,一斤白菜,一斤莲藕,然后你通过这三种食材,可以依靠自己高超的厨艺来做成不同味道的菜品,你可以炖汤,可以清炒,可以红烧,这样你就做出了不同的菜品。
从这个例子来理解:这一斤排骨,一斤白菜,一斤莲藕就是你的原材料,这就是你的类,而你通过这个原材料,来做出各种菜式,各种菜式,也就可以理解成你由这个类定义出来的对象。
1.2类和对象的关系
由上面的定义可以得出,对象是由类定义出来的,对象的特征属性,也是由类决定的。
同时我们可以得出一个结论:一个类,是可以定义出多个对象的!!!
注意:
1.类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员。
2.类是一种自定义的类型,可以用来定义变量。3.一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量。
4.做个比方,类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东
西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空
间。
2.类的使用
应注意:
1.类名要采取大驼峰定义,方法名和变量名采取小驼峰。
如果黄色表示这个Java文件的类名,需要用大驼峰的形式;绿色分别表示变量和方法名,需要用小驼峰的形式。
2.一般一个Java文件定义一个类。
3.此处写的方法不带static关键字。
要理解:static修饰的是静态变量和静态方法,而静态变量和静态方法不属于某个具体的对象,是所有对象所共享的。是类的属性,不存储在某个对象的空间中。
4.成员前写法统一为public。
如下图:
前期,我们的成员一般统一为public。
5.public修饰的类必须要和文件名相同。
第二点我们提到一般一个文件只定义一个类,但我们定义两个类或者更多的类也是没有错误的。
如下图:
我们定义的TestDog这个类是由public修饰的,这个类名是必须和文件名一样,如果需要定义多的类名,就无需再添加public了。
6.main方法所在的类一般要使用public修饰 。
如下图:
7.不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改 。
如下图:
3.类的实例化
1.前文中我们所讲,对象是由类实例化出来的,而用类创建对象的过程,称为类的实例化。
2.只有实例化出来的对象才会占用实际空间。
3.Java实例化采用new关键字。
4.实例化完成后的对象使用 . 来访问对象的属性和方法。
5.前文我们也提到,一个类是可以实例化多个对象的。
实例如下图:
黄色表示由new关键字实例出来的对象; 蓝色表示使用 . 来访问对象的属性和方法。
如下图:
表示一个类是可以实例化多个对象的。
这里还需要强调一个重点:方法是不占内存的,调用方法的时候才会给它开内存,调用后在栈帧上开内存,所以在对象里面是不存在方法的,只是存放方法的地址!!!
4.this
4.1 this的引出
首先我们先来看一段代码:
public class Date {
public int year;
public int month;
public int day;
public void setDay(int y, int m, int d){
year = year;
month = month;
day = day;
}
}
现在思考:
函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?
现在引出this:this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该
引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
也就是如果我们采取以下的代码格式,代码的思路就会更佳的清晰易懂:
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
}
值得我们注意的是:this引用的是调用成员方法的对象。
现在上图代码中:左边的this.year就表示成员变量year,右边的year就表示函数参数year,代码意思就是用函数传来的参数year赋值给成员变量year。
然后我们再回到第一段代码,没有this的引用,我们知道在函数内部,局部变量是占主导地位的,所以类似于用参数 year = year 这样的代码,只是参数赋值给参数,并没有本质上去改动成员变量year,所以最后输出成员变量year的时候,就会默认输出0。(这就要联系到下面讲到的默认初始化了。)
如下图:
4.2 this引用的特征
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型。
2. this只能在"成员方法"中使用。3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象。
简单来说:this表示对当前对象的引用,谁调用这个方法,谁就是this。
4.3 this的三种用法
1.this.成员变量
2.this.成员方法
3.this() 访问构造方法(下文会讲到)
根据我们上文的讲解,第一点和第二点的用法是相似的,下面以一个例子来进行演示
如下图:
5.构造方法
首先,我们要知道一点重要的点:只要构造了对象,就一定会有构造方法。
5.1构造方法的概念
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且
在整个对象的生命周期内只调用一次。没有返回值类型,设置为void也不行。
一般情况下使用public修饰。
举例说明:
对应的构造方法可以传参数,也可以不传参数,这就说明了构造方法可以重载。
5.2构造方法的特性
1. 名字必须与类名相同。
2. 没有返回值类型,设置为void也不行。
3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)。
4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)。
强调重点 :
实例化对象后,就一定会调用构造方法的!!!
当我们没有提供任何的构造方法的时候,编译器会帮我们提供一个不带参数的构造方法,但是如果我们一旦字节定义了构造方法,编译器将不再为我们提供构造方法了!!!
对应的一个易错点:
5.3构造方法和this的结合用法——this的第三种用法
this(); 访问构造方法
当存在两种构造方法的时候:
以上这种情况,就是this的第三种用法,就是在一种构造方法中,出现了this()另一种构造方法的格式的时候,就会跳跃调用,再放回调用原构造方法。
但是有两个易错点是需要我们注意的:
1.this();这一条语句是必须放在第一行的。
2.不能形成环,这样就是无限循环调用了。例如:
所以这样就会发生错误,以上两个易错点是需要我们特别注意的。
6.初始化
6.1 默认初始化
通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。
与此不同的是,如果是在实例化后的对象里,定义一个成员变量而没有初始化是可行的。当没有初始化的时候,就引出了默认初始化这一概念。默认初始化:实例化对象中的成员变量没有初始化的时候,编译器会给没有初始化的成员变量默认初始化。
不同类型的变量对应不同的初始化,如下图:
6.2就地初始化
在定义成员变量时,就直接赋初值。
7.封装
面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性;
而封装特性的意思就是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来喝对象进行交互。
7.1访问限定符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认
知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
1.private ( 私有的):类的private成员只能被同一个包中同一个类的成员访问。
2.default (默认的):类的成员什么修饰符都没有,又叫包修饰符,只有类本身成员和当前包下类的成员可以访问。
3.protected (受保护的):类的protected成员可以被同一个包中的相同或不同类的成员访问,也可以被不同包的子类成员访问。
4.public(公开的):类的public成员所有类的成员都可以访问。
一般情况成员变量设置为
private
,成员方法设置为public
。
7.2包
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
包有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
简单理解:同一个包其实就是同一个文件夹下的类。
导入包中的类
1.可以使用 import语句导入包。(要注意,不能导入指定包,导入的应该是具体包中的类!!!)
2.可以使用
import java.util.*
使用此包中所有的类。3.可以使用import static导入包中静态的方法和字段。
4.建议显式的指定要导入的类名. 否则还是容易出现冲突的情况。如下:
自定义包
1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> package。
2. 在弹出的对话框中输入包名, 例如 Test。
3. 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可。
4. 同时我们也看到了, 在新创建的 Test1.java 文件的最上方, 就出现了一个 package 语句。
8.static
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
8.1静态成员变量特征
1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中。
2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问。
3. 类变量存储在方法区当中。
4. 生命周期伴随类的一生。(即:随类的加载而创建,随类的卸载而销毁)
静态成员变量是不依赖于对象的,直接用类名创建就行了。
8.2静态成员方法特征
1. 不属于某个具体的对象,是类方法。
2. 可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者。
3. 不能在静态方法中访问任何非静态成员变量。(但是非静态方法可以访问静态成员变量)
错误分析 :
这样是错误的,不能在静态方法中不能直接访问非静态的数据成员和成员方法!!!
因为非静态方法有this
参数,静态方法中调用时候无法传递this引用。
9.代码块
使用 {} 定义的一段代码称为代码块。
9.1普通代码块
普通代码块:定义在方法中的代码块
比较少见 ,代码块中的代码一定会执行,不受条件限制!!!
9.2实例(构造)代码块
构造代码块一般用于初始化实例成员变量。
9.3静态代码块
一般用于初始化静态成员变量。
9.4 实例分析
从此我们可以得出结论:这段代码打印跟代码的前后关系是无关系的,而真正的打印顺序是:静态代码块>实例代码块>构造方法。
再看下一个例子:
我们可以看出,当把实例化语句去掉时,只执行了静态代码块,由此可以得出静态代码块不需要实例化也可以执行,而另外两者不可以。
这是因为类在被加载时,静态代码块就被执行了。
再看下一个例子:
由此我们可以得出一个结论,静态的只会执行一次,而另外两者实例化一次就执行一次!!!
总结:由此我们可以看出
1.静态代码块不管生成多少个对象,其只会执行一次。
2.静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的。
3.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)。
4.实例代码块只有在创建对象时才会执行。