一:类的实例化
1:什么是实例化
定义了一个类,就相当于在计算机中定义了一种新的数据类型,与int,double类似,只不过int,double是java语言自带的内置类型,而类是我们自己自定义了一种新的类型。
用类类型创建对象的过程,叫作类的实例化。在java中采用new 关键字完成对类的实例化。
下面我将举个例子,创建一个Dog类来解释一下。
class Dog{//定义了一个Dog类 public String name;//定义Dog类的name成员变量 public int age;//定义Dog类的age成员变量 public String color;//定义Dog类的color成员变量 public void barks(){//定义Dog类的barks成员方法 System.out.println(name+"摇尾巴"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog();//通过new关键字创建了一个Dog类 dog.name="阿黄";//通过.来访问对象中的属性 dog.barks();//通过.来访问对象中的方法 } }
2:类和对象的关系
1:类只是一个模型一样的东西,是对对象的描述,比如是那么的例子,Dog类中有成员变量name,age,color,就像狗有名字,年龄,颜色,我们把狗的这些属性抽取出来,定义一个类,用这个类来描述狗这个实体。
2:类是一种自定义类型,可以用来定义变量。
3:一个类可以实例化多个对象,实例化的对象会占用内存空间。
二:类的初始化
1:就地初始化
就地初始化就是自己根据实际问题,进行初始化。
方法一:
class Dog{//定义了一个Dog类 public String name;//定义Dog类的name成员变量 public int age;//定义Dog类的age成员变量 public String color;//定义Dog类的color成员变量 public void barks(){//定义Dog类的barks成员方法 System.out.println(name+"摇尾巴"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog(); /* 初始化Dog的成员变量 */ dog.name="阿黄"; dog.age=3; dog.color="黄色"; } }
方法二:
class Dog{//定义了一个Dog类 /* 在定义Dog类的同时对其初始化 */ public String name="阿黄"; public int age=3; public String color="黄色"; public void barks(){//定义Dog类的barks成员方法 System.out.println(name+"摇尾巴"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog(); } }
2:默认初始化
类中的成员变量不像局部变量,不初始化就不可以使用,类在实例化对象的时候,就默认给类的成员变量进行初始化了。int 类型的数据默认值是0,String类型的默认值是0;举例说明一下(哈哈)。
class Dog{//定义了一个Dog类 /* 在定义Dog类的同时对其初始化 */ public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println(name+"摇尾巴"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog(); System.out.println("姓名: "+dog.name+" 年龄: "+dog.age+" 颜色: "+dog.color); } }
三:this引用
1:先看一个日期类的例子
class Date{ public int year; public int month; public int day; public void setDay(int y,int m,int d){ //三个形参:year,month,day year=y; month=m; day=d; } public void printDate(){ System.out.println("year:"+year+" month:"+month+" day:"+day); } } public class Test { public static void main(String[] args) { Date date =new Date(); date.setDay(2023,11,4);//实参 date.printDate(); } }
看一下输出:
当我们的形参名和成员变量名相同时:
class Date{ public int year; public int month; public int day; public void setDay(int year,int month,int day){ //三个形参:year,month,day year=year; month=month; day=day; } public void printDate(){ System.out.println("year:"+year+" month:"+month+" day:"+day); } } public class Test { public static void main(String[] args) { Date date =new Date(); date.setDay(2023,11,4);//实参 date.printDate(); } }
为什么结果全变成默认值了呢?
这是因为当形参名和成员变量名相同的时候,赋值语句是给形参赋值,而不是给类的成员变量赋值。
再看一段代码:
class Date{ public int year; public int month; public int day; public void setDay(int year,int month,int day){ //三个形参:year,month,day this.year=year; this.month=month; this.day=day; } public void printDate(){ System.out.println("year:"+year+" month:"+month+" day:"+day); } } public class Test { public static void main(String[] args) { Date date =new Date(); date.setDay(2023,11,4);//实参 date.printDate(); } }
输出的结果是:
这里的结果又正常了,这是为什么呢?视力好的小伙伴可能发现了在赋值语句处,出现了:this.。this.叫作this引用。
2:什么是this引用
this引用指的是对当前对象的引用,使用this.就表示对当前对象的成员方法操作。
3:this引用的特点:
1:this引用的类型:调用哪个对象,类型就是哪个对象
比如上面的Date类,这里的this引用的类型就是Date.
2:this只能在成员方法中使用。
3:this是成员方法中的第一个隐藏的参数,编译器会自动传递
class Date{ public int year; public int month; public int day; public void setDay(Date this,int year,int month,int day){//加上Date this编译器并不会报错 this.year=year; this.month=month; this.day=day; } public void printDate(){ System.out.println("year:"+year+" month:"+month+" day:"+day); } } public class Test { public static void main(String[] args) { Date date =new Date(); date.setDay(2023,11,4);//实参 date.printDate(); } }
4:this 的使用
public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println("name:"+name+"摇尾巴!!");//this.成员变量,访问成员变量 this.fun();//this.成员方法,访问成员方法 } public void fun(){ System.out.println("哈哈"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog(); dog.barks(); } }
四:构造方法
1:构造方法的概念:
构造方法是一个特殊的的成员方法,方法名必必须和类名相同,没有返回值,在创建对象的时候,编译器会自动调用,如果我们不添加任何的构造方法,编译器也会提供一个不带参数的构造方法,所以构造方法至少有一个。
但如果一个类提供了任意一种的构造方法,编译器都不会再提供不带参数的构造方法。
在大多数的情况下,构造方法使用public来修饰。
2:构造方法的作用:
构造方法的作用就是对对象中的成员进行初始化,但不负责给对象开辟空间。
实例化对象的时候,一定会调用合适的构造方法(根据参数列表调用)
对象的产生有2步:
1:为对象分配内存,
2:调用合适的构造方法。
3:构造方法的特点:
1:方法名必须和类名相同;
2:没有返回值类型,返回类型为void也不行;
3:创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次;
4:构造方法可以重载。
5:在构造方法中,可以通过this来调用其他构造方法,当this这条语句必须放在方法的第一行。
class Dog{//定义了一个Dog类 public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println("name:"+name+"摇尾巴!!"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog();//在new对象,也就是在创建对象的时候,调用构造方法, // 此时我们没有提供构造方法,编译器会提供一个不带参数的构造方法 dog.barks(); } }
class Dog{//定义了一个Dog类 public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println("name:"+name+"摇尾巴!!"); } //提供带3个参数的构造方法 public Dog(String name, int age, String color) { this.name = name; this.age = age; this.color = color; } } public class Test { public static void main(String[] args) { Dog dog=new Dog();//我们提供了一个带3个参数的构造方法,编译器不会再提供不带参数的构造方法, // 所以编译器会报错 dog.barks(); } }
构造方法的正确使用:
class Dog{//定义了一个Dog类 public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println("name:"+this.name+"摇尾巴!!");//this.成员变量 this.fun();//this.成员方法 } //提供带3个参数的构造方法 public Dog(String name, int age, String color) { this.name = name; this.age = age; this.color = color; } //不带参数的构造方法 public Dog() { } public void fun(){ System.out.println("哈哈"); } } public class Test { public static void main(String[] args) { Dog dog=new Dog("来福",3,"黄色"); //传入三个参数,所以会调用带三个参数的构造方法 dog.barks(); } }
在构造方法中调用其他的构造方法:
class Dog{//定义了一个Dog类 public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println(this.name+"摇尾巴!!");//this.成员变量 } //提供带3个参数的构造方法 public Dog(String name, int age, String color) { this.name = name; this.age = age; this.color = color; } //不带参数的构造方法 public Dog() { this("来福",3,"黄色");//通过this关键字来调用带三个参数的构造方法,请必须放在方法的第一行 } } public class Test { public static void main(String[] args) { Dog dog=new Dog();//调用不带参数的构造方法 dog.barks(); } }
构造方法不能形成环:
class Dog{//定义了一个Dog类 public String name; public int age; public String color; public void barks(){//定义Dog类的barks成员方法 System.out.println(this.name+"摇尾巴!!");//this.成员变量 } //提供带3个参数的构造方法 public Dog(String name, int age, String color) { this();//调用不带参数的构造方法 this.name = name; this.age = age; this.color = color; } //不带参数的构造方法 public Dog() { this("来福",3,"黄色");//通过this关键字来调用带三个参数的构造方法,请必须放在方法的第一行 } } public class Test { public static void main(String[] args) { Dog dog=new Dog();//调用不带参数的构造方法 dog.barks(); } }
在这个例子中,在不带参数的构造方法中调用带3个参数的构造方法,然后又在带3个参数的构造方法中调用不带参数的构造方法,你调它,它调你,永远结束不了,所以不允许这样使用。