本文对Java中的类与对象,权限访问修饰符,static,代码块,内部类相关知识进行解析与总结。
类与对象的关系:类是相同类型对象的集合,对象是类的实例化。
类是一种自定义的数据类型,其中包括数据的属性(成员变量)以及能完成的行为(成员方法)。
定义类:[权限修饰符] class 类名{
[成员变量;]
[成员方法;]
[构造方法;]
}
如:
类中成员变量与成员方法
成员变量:在类中定义的变量,该变量用于描述该类对象的属性。
成员方法:在类中定义的方法,该方法用于在main中被调用 以此完成该类对象能完成的行为。
注意:类名使用大驼峰命名法(即不管是单个还是多个单词,这些单词首字母都大写)。
在每个类文件中只能有一个public修饰的类,一般建议一个类文件中只创建一个类。
类成员的使用:
对象名.成员变量名; 这个整体就是该对象的对应成员变量
对象名.成员方法名(方法的参数列表); 这个整体就表明此处调用了该对象的对应成员方法。
对成员变量赋值的三种方法:
1.构造方法
2.set方法
3.main中直接赋值。
就地初始化:在类中创建成员变量时直接赋值,不常用。
默认初始化:即对成员变量赋值,编译器会给定默认值。
构造方法是一种特殊的成员方法,该方法名字必须与类名相同且没有返回类型,在创建对象时由编译器自动调用,并且在整个对象的生命周期中只调用一次。
当在定义类的时候没有构造方法,编译器会默认提供一个无参构造方法,在人为给定构造方法之后该默认无参构造方法会消失。
类的实例化:用类来创建对象的过程。
一般使用new语句来实例化对象,在堆区上申请空间new了一个对象,此空间中存有对象的成员方法与成员变量,最后将此空间的地址传给main中该类的引用类型局部变量。
注意:类本质上也是引用数据类型。
成员变量不同于局部变量,成员变量具有默认初始值,默认初始值与数组元素对应类型默认值相同
实例化同一个类中多个对象时,这多个对象各自占有堆区中的不同空间(指向的对象不同)。
this引用:当前对象的引用。
当成员方法中形参名与该类中成员变量名相同时,使用this.成员名,这个整体就为该类的成员变量。本质上在局部区域之内,局部变量(形参)会覆盖成员变量(优先级较高),所以使用this区分。
注意:1.this.成员名是哪个对象调用该语句就是哪个对象的成员变量
2.this只能在成员方法中使用
3.在成员方法中this只能引用当前对象,不能再引用其他对象。
实例化对象最重要的两步:
1.在堆区中申请内存(new语句后编译器完成)
2.调用合适的构造方法
注意:构造方法可以进行方法的重载。
可在构造方法中用this(参数列表)来调用本类的其他构造方法,
this();为调用本对象的构造方法,不过此种写法必须放在构造方法里面并且需写在方法内第一行,调用的到底是哪一个构造方法,具体根据调用方法的参数列表区别。
如三个参数的构造方法先使用this(参1,参2); 再this.成员变量3名=参3;在调用两个参数的构造方法时成员1与成员2已经完成赋值。
还可以使用this.成员方法名(参数列表) 将此整体写在类中其他区域,实现在一个成员方法中调用另一个成员方法。
JVM在new对象时发生的事件:
1.检测对象对应的类是否加载
2.为对象在堆区中分配空间
3.处理多线程问题
4.给对象成员变量赋予默认值
5.设置对象头信息
6.调用构造方法,给对象中各个成员赋值
封装-面向对象思想
定义:将数据和操作数据的方法有机结合,隐藏对象的属性与实现细节,仅对外公开接口来和对象进行交互。
封装,继承,多态是面向对象的三大思想,除此之外还有其他面向对象的思想。
封装依靠访问权限限定修饰符实现。
四种权限:private,default,protected,public。
其中defualt为默认权限项。
public:在任何地方都可以访问它修饰的类/方法/变量。
default:在同一包中所有类访问。
private:只能在当前类(定义此类的代码块)中访问。
protected:在同一包中所有类或者不同包中子类能访问。
对于被private修饰的变量,只能在此类中被访问,此时我们可以创建set与get方法来对该变量赋值与取值,也可以使用show,print等其他方法来使用该变量。
在修饰事物时需认真考虑权限,优先使用权限小的修饰符。
包:一组类的集合
导包语句如:improt java.util.*; 此语句表示将java.util路径下的文件包中的类导入当前文件中,在此步骤之后就能使用util包下包含的类的方法,但不是将所有类都导入,而是用到哪个类编译器就自动导入哪个类。
注意:文件中也可以使用import语句导入某个类中的所有静态方法。
格式:import static java.包名.类名.*;
自定义包:
在文件的最上方加package语句指定该代码在哪个包中
包名需要尽量指定成唯一的名字
包名要与代码路径相匹配。
如果一个类中无package语句,则该类被放到一个默认的包中。
若在包1与包2中有同名类Test,则在包2中new Test对象时默认new出的是包2的Test类对象,若要new出包1中的同名类对象,则 包1名.同名类名 对象名 = new 包1名.同名类名();
static静态修饰符:
static成员:被static修饰的成员称之为静态成员或者类成员,其不属于某个具体的对象而是这个类new(实例化)出来的所有对象共享的。
静态成员变量储存在方法区(一块独特的区域),在对象的空间中不占有储存空间。
静态成员变量可用对象引用访问也可用类名引用访问,建议使用类名引用访问。
静态成员变量随类的加载而创建,随类的卸载而销毁。
静态方法(static修饰的类成员方法)也可以通过类名访问。静态方法(类方法)不属于某个对象,而属于类。
若非要访问依赖于对象的(无static修饰)成员变量或方法,则先在静态方法中new个对象,再使用该对象的引用来访问,或者在静态方法的参数列表中给了一个当前类的参数,再通过该类对象的引用完成访问。
拓展:
main函数可以不是静态的,但在JVM中被人实现规定为静态的。
final修饰的载体(常量)必须要人为赋值。
将对象赋值为null表示该对象不指向任何有用的空间(不指向任何有用的对象),但是如果要使用该对象来调用static修饰的类方法,该调用是正确的,因为类方法不依赖于对象。
静态变量不能定义在类的方法里面,因为若在方法内部定义静态变量,该变量就不是静态变量而是局部变量了。
本质:在类中构造方法与普通方法的参数列表中一般都有隐藏本类的对象参数this(一个以本类为数据类型的参数,参数名为this),static修饰的方法没有此参数,而所有本类对象的成员变量或者方法在调用时名称之前都隐藏了this.这个整体,static没有这个对象参数,自然不能直接使用本类的成员。
在静态方法中无法直接使用非静态事物也是这个道理,无法直接使用我们就创建对象或者传参进行使用。
注意:静态方法不能重写,不能实现多态。
类中代码块:
代码块概念:使用{}定义的一段代码称为代码块。
代码块分为普通代码块,构造块,静态块与同步代码块。
普通代码块(本地代码块):定义在某个方法内的代码块。
构造块(实例代码块):定义在类的内部方法的外部,一般用来给成员赋值。
静态块:用static修饰的构造块,一般用来给静态成员赋值。
在同一类中的运行顺序(加载顺序):静态代码块—实例代码块—构造方法。
若多个代码块属于同一类型(静态/实例/构造),则这多个代码块的执行顺序从上往下。
而若根据有静态代码块的类创建多个对象,这多个对象中只有第一个执行静态代码块,其他不执行。
静态成员变量是类的属性,是在JVM加载类时开辟空间并初始化的。
实例代码块与构造方法只有在创建对象时会执行。
内部类:定义在另一个类的内部的类,“另一个类”称为外部类。
内部类也算一个类,所以会生成对应的字节码文件,字节码文件名为外部类名$内部类名。
内部类分为:
1.实例内部类
2.静态内部类
3.本地内部类
4.匿名内部类
实例内部类:
实例内部类中不能定义静态成员变量,也不能定义静态成员方法,因为实例内部类本质上也是外部类的一个普通成员,也依赖于对象,如果非要定义静态成员变量则需要用final修饰,而静态方法没有办法解决定义问题。
实例内部类的实例化:
1.使用外部类对象(外部类引用)
格式:外部类类名.内部类 变量名 = 外部类引用.new 内部类();
若内部类中成员变量与外部类成员变量名字相同,在内部类中优先内部成员变量。若非要使用外部成员变量,使用:外部类名.this.成员变量名 这个整体表示外部类的那个成员变量。本质上内部类的方法参数列表中不仅隐藏了该内部类的对象,还隐藏了外部类的对象。若为同名静态变量,直接使用 外部类名.成员变量名 这个整体。
实例内部类的缺点:创建时若要new对象,必须先new外部类的对象。
总结:
1.外部类的成员都可以在内部类中直接访问。
2.实例内部类所处位置与外部类成员的位置相同,即实例内部类也受访问权限修饰符的约束。
3.实例内部类与外部类的成员同名时优先访问自己的,若要访问外部类成员,则使用 外部类名.this.成员名 访问
4.实例内部类对象必须在先创建了外部类对象的基础之上创建。
5.实例内部类中非静态方法包含了一个指向外部类对象的引用。
6.外部类中不能直接访问实例内部类中的成员,若要访问则先创建内部类对象。
静态内部类:static修饰的实例内部类
1.获取静态内部类对象:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
2.不能在静态内部类中直接访问外部类非静态的数据成员,若要访问则先new一个外部类对象,通过对象引用访问,或者在创建内部类时传入一个外部类对象参数,通过该参数引用访问。
注意:一个外部类不能是静态的。
局部内部类:定义在方法里面的类,该类不能使用权限访问修饰符修饰,使用也只能在当前方法里面使用,编译器也会为它生成字节码文件,文件格式:外部类名.内部类名.class
匿名内部类:
匿名对象
即在new一个类的对象时不使用变量来承接,普通的对象经过变量承接之后可以使用该变量进行多次对成员的使用。因为没有标识符,匿名对象无法指定使用,所以匿名对象在创建时就要使用目的成员,所以匿名对象只能使用一次。
匿名内部类
在main中定义与使用,new 外部类名(){};
花括号中可以定义成员变量或方法,方法的使用如上图,在最外层花括号后面 .方法名(参数列表) 来调用定义的方法。
END。