JAVA SE:认识类和对象
目录
1.简单认识类
1.1类的定义格式
1.2举例(狗类)
2.类的实例化
3.this引用
3.1什么是this
3.2this的使用
1.this.成员变量
2.this.成员方法
3.this() 调用其他对象的构造方法
4.构造方法
4.1概念与使用
4.2补充:this() 调用其他对象的构造方法
5.关键词static
5.1static修饰成员变量
5.2static修饰成员方法
5.3.1 就地初始化
5.3.2 静态代码块初始化
普通代码块
构造代码块(实例代码块)
静态代码块
三者执行顺序问题
6.对象的打印
1.简单认识类
类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干 啥),描述完成后计算机就可以识别了。
比如:洗衣机,它是一个品牌,在Java中可以将其看成是一个类别。
属性:产品品牌,型号,产品重量,外观尺寸,颜色...
功能:洗衣,烘干、定时....
1.1类的定义格式
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类 具有哪些功能,称为类的成员方法。
1.2举例(狗类)
public class Dog {
public String name;//成员变量
public int age;
public String color;
//成员方法
public void eat(){
System.out.println("吃饭...");
}
public void bark(){
System.out.println("汪汪...");
}
}
2.类的实例化
用类类型创建对象的过程就是类的实例化。
看代码:
public class Test {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.color = "red";
dog1.age = 6;
dog1.name = "坤坤";
dog1.bark();
dog1.eat();
Dog dog2 = new Dog();
dog2.color = "blue";
dog2.age = 9;
dog2.name = "篮球";
dog2.bark();
dog2.eat();
}
}
这段代码就是通过Dog类实例化两个对象dog1和dog2。
这里的知识点:
new 关键字用于创建一个对象的实例.
使用 . 来访问对象中的属性和方法.
同一个类可以创建多个实例.
类就像是一张图纸,只设计出需要什么东西,但是并没有实体的建筑存在。
3.this引用
当我们有一个setDog的类用于对成员变量进行初始化,我们这样写就会产生问题:
public void setDog(String name,int age,String color){
name = name;
age = age;
color = color;
}
我们实例化对象dog3来调用setDog方法初始化,在进行打印dog3的名字、年龄和颜色。
Dog dog3 = new Dog();
dog3.setDog("山鸡",10,"yellow");
System.out.println(dog3.age);
System.out.println(dog3.color);
System.out.println(dog3.name);
结果输出如下:
电脑搞不清楚函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?成员变量参数?估计长时间不看代码,我们自己都搞不清楚。这就引出了this。
3.1什么是this
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成(this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法 对象的引用传递给该成员方法,this负责来接收)。
public void setDog(String name,int age,String color){
this.name = name;
this.age = age;
this.color = color;
}//this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
这样修改就可以更正上面产生的问题。
3.2this的使用
1.this.成员变量
拿一个使用场景举例:
public void show(){
System.out.println(" 姓名:" + this.name
+ " 年龄: " + this.age
+ " 颜色: " + this.color );
}
调用一下看看:
2.this.成员方法
public void eat(){
this.bark();
System.out.println("吃饭...");
}
public void bark(){
System.out.println("汪汪...");
}
使用一个对象调一下eat方法,bark也会被调用。
3.this() 调用其他对象的构造方法
这个先卖个关子,会在构造方法里补充!!!
4.构造方法
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
4.1概念与使用
还是狗类,我们给狗类里写一个无参数的构造器。看看是否在创建对象时被自动调用。
public Dog(){
System.out.println("这个无参被调用了....");
}
创建一个对象dog4。并且运行一波:
构造器是支持重载的,我们当然可以根据需要的情况写很多个,我在写一个有参的:
public Dog(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
System.out.println("这个是有参的,被调用了.....");
}
我们还用dog4。
public static void main(String[] args) {
Dog dog4 = new Dog("丽丽",1,"white");
dog4.show();
}
用show方法打印一下,看结果(还是会自动先调用构造方法的):
注意:
如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
一旦用户定义,编译器则不再生成。
4.2补充:this() 调用其他对象的构造方法
我们把上面写的两个构造方法拿来稍微改下:
public Dog(){
this("丽丽",1,"white");
System.out.println("这个无参被调用了....");
}
public Dog(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
System.out.println("这个是有参的,被调用了.....");
}
用dog4来调用无参,由于this它会先调用有参。
注意:
不能在两个构造里用this()相互调用。不能形成环,代码错误。
5.关键词static
使用前面的Dog类实例化了dog1 、dog2、dog3 、dog4。它们有各自的名字、颜色和年龄。现在我们假设它们都是小型犬。我们如果在增加一个成员变量size。那么每个对象都会存储一个。因为需要使用这些信息来描述具体狗的信息。而现在要表示狗的大小,这狗的大小的属性并不需要每个对象中都存储一份,而是需要让所有的狗来共享。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
5.1static修饰成员变量
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
我们增添一个由static修饰的成员变量size在Dog类中:
public static String size;
具体的使用和注意事项由代码展现:
5.2static修饰成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
public class Student{
// ...
private static String classRoom = "Bit306";
// ...
public static String getClassRoom(){
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
静态成员方法可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者 。
需要注意的是:
在静态成员方法中是不能访问任何非静态变量,当然也不能调用非静态方法(就更不能使用this了)。
5.3static修饰的成员变量的初始化
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化
5.3.1 就地初始化
在定义的时候就初始化
public class Dog{
//形如
private static String size = "small";
//..
}
5.3.2 静态代码块初始化
先要解决什么是代码块???
使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字 。
我们来了解三种代码块:普通代码块、构造代码块和静态代码块
普通代码块
定义在方法中的代码块,平常使用比较少。
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 执行结果
x1 = 10
x2 = 100
构造代码块(实例代码块)
在类中使用的代码块,一般用来初始化实例成员变量。
public class Dog {
private String name;//成员变量
private int age;
private String color;
private static String size = "small";
public Dog(){
System.out.println("这个无参被调用了....");
}
public Dog(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
}
{
this.name = "lili";
this.age = 19;
this.color = "red";
}
public void show(){
System.out.println(" 姓名:" + this.name
+ " 年龄: " + this.age
+ " 颜色: " + this.color );
}
}
public class Test {
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.show();
}
}
//运行结果
//这个无参被调用了....
//姓名: lili年龄: 19 颜色: red
静态代码块
使用static定义的代码块称为静态代码块 。一般用于初始化静态成员变量 。
public class Dog {
private String name;//成员变量
private int age;
private String color;
private static String size = "small";
public Dog(){
System.out.println("这个无参被调用了....");
}
public Dog(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
}
//实例代码块
{
this.name = "lili";
this.age = 19;
this.color = "red";
}
static{
size = "big";
System.out.println("static代码块!!!");
}
public void show(){
System.out.println(" 姓名:" + this.name
+ " 年龄: " + this.age
+ " 颜色: " + this.color );
}
}
public class Test {
public static void main(String[] args) {
Dog dog1 = new Dog();
Dog dog2 = new Dog();
}
}
//运行结果
//static代码块!!!
//这个无参被调用了....
//这个无参被调用了....
注意:
静态代码块不管生成多少个对象,其只会执行一次。
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
实例代码块只有在创建对象时才会执行
三者执行顺序问题
1.普通代码块就按顺序执行、静态代码块在类加载是执行、实例代码块在创建对象时执行。
2.多个静态代码块,和定义顺序有关。
3.实例代码块和静态代码块都存在的时候,先执行静态代码块。
6.对象的打印
还是这个类
public class Dog {
private String name;//成员变量
private int age;
private String color;
private static String size = "small";
public Dog(){
System.out.println("这个无参被调用了....");
}
public Dog(String name,int age,String color) {
this.name = name;
this.age = age;
this.color = color;
System.out.println(2);
}
//实例代码块
{
this.name = "lili";
this.age = 19;
this.color = "red";
System.out.println(1);
}
static{
size = "big";
System.out.println("static代码块!!!");
}
public void show(){
System.out.println(" 姓名:" + this.name
+ " 年龄: " + this.age
+ " 颜色: " + this.color );
}
}
public class Test {
public static void main(String[] args) {
Dog dog1 = new Dog();
Dog dog2 = new Dog();
}
}
//运行结果
//static代码块!!!
//这个无参被调用了....
//这个无参被调用了....
我们这样调用:
public class Test {
public static void main(String[] args) {
Dog2 dog1 = new Dog2("shaniao",1,"black");
System.out.println(dog1);
}
}
运行结果:
static代码块!!!
1
2
Dog2@3b07d329//输出了dog1引用的地址
但是当我们重写toString方法。
public String toString(){
return " 姓名:" + this.name
+ " 年龄: " + this.age
+ " 颜色: " + this.color
+ " 尺寸: " + size;
}
还是刚才的dog1调用会产生不一样的结果: