![在这里插入图片描述](https://img-blog.csdnimg.cn/c672e363aca44f53ba272da6dcad2e4f.jpeg)
初识面向对象
什么是面向对象
Java属于面向对象语言,C语言则是面向过程语言。Java是一门纯面向对象的语言(Object Oriented Program,简称OOP),面向对象会有三个特性:继承,封装,多态。在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。像C++也是一个面向对象语言。
面向对象与面向过程的区别我们可以用在家自己做饭吃和去饭店吃饭做区别。在家吃饭自己得需要买食材,做饭,吃饭,刷碗,其中做饭的过程是需要自己解决的,这属于面向过程。在饭店吃饭的话,你只需要找到饭馆去吃饭就行了,饭店如何做饭的过程不是需要关注的们需要关注的是饭店这个对象。
自己做饭吃注重的是这个过程少一个过程就不行。按照该种方式来写代码,将来扩展或者维护起来会比较麻烦。
去餐馆吃饭总共三个对象:钱,人,餐馆。
以面向对象方式来进行处理,就不关注做饭的过程,具体饭店是如何买菜,做菜的,用户不用去关心,只需要人进入餐馆,点餐付钱即可,通过对象之间的交互来完成的。
注意:面向过程和面相对象并不是一门语言,而是解决问题的方法,没有那个好坏之分,都有其专门的应用场景。
类的定义和实例化
一个餐馆计算机不能识别,可以简化有地址,开张时间,名称等等。简化的抽象结果计算机也不能识别,开发人员可以采用某种面相对象的编程语言来进行描述,比如:Java语言。
类的定义格式
什么是类?
- 类是用来对一个实体(对象)来进行描述的,主要描述该实体(对象)具有哪些属性(外观尺寸等),哪些功能(用来干啥),描述完成后计算机就可以识别了。
定义一个狗类:
狗的属性有毛发颜色,名字,年龄等。行为有汪汪叫,摇尾巴等。
class PetDog{
//属性 -> 成员变量
public String name;
public int age;
public String colour;
//行为 -> 成员方法
public void barks(){
System.out.println(name + "汪汪叫");
}
public void wag(){
System.out.println(name + "摇尾巴");
}
}
class为定义类的关键字,PetDog为类的名字,{}中为类的主体。
- 类中包含的内容称为类的成员。
- 属性主要是用来描述类的,称之为类的成员属性或者类成员变量。
- 方法中主要说明类具有哪些功能,称为类的成员方法。
类名注意采用大驼峰定义,方法名用小驼峰定义。
成员前写法统一为public,还有此处写的方法不带 static 关键字. 后面会详细解释
-
一般一个文件当中只定义一个类
-
main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
-
public修饰的类只有一个并且必须要和文件名相同
-
不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改
类的实例化
定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:PetDog类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。
用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
实例化狗类
class PetDog{
//属性 -> 成员变量
public String name;
public int age;
public String colour;
//行为 -> 成员方法
public void barks(){
System.out.println(name + "汪汪叫 " + age + "岁 " + colour);
}
public void wag(){
System.out.println(name + "摇尾巴 " + age + "岁 " + colour);
}
}
public class Test {
public static void main(String[] args) {
PetDog dog1 = new PetDog();//new 关键字用于创建一个对象的实例.
dog1.name = "来福";//使用 . 来访问对象中的属性和方法.
dog1.colour = "黄色";
dog1.age = 5;
dog1.barks();
dog1.wag();
PetDog dog2 = new PetDog();
PetDog dog3 = new PetDog();
PetDog dog4 = new PetDog();
PetDog dog5 = new PetDog();//一个类可以实例化无数个对象
}
}
输出结果:
来福汪汪叫 5岁 黄色
来福摇尾巴 5岁 黄色
以上实例化可以得出三点结论:
- new 关键字用于创建一个对象的实例.
- 使用 . 来访问对象中的属性和方法.
- 一个类可以实例化无数个对象
类和对象的说明:
1.类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
2. 类是一种自定义的类型,可以用来定义变量.
3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
4.类是不占据空间的,占据空间的是实例化出来的对象。学过C语言的人一看到这个就联想到了结构体也是这样的。类就相当于是一张建筑图纸可以看作不占据空间的,对象相当于用建筑图纸建造出来的建筑物,是占据空间的。
this引用
为什么用this引用
定义一个日期类,创建对象并调用成员方法赋值成员变量
public class TestDate {
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
year = year;
month = month;
day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
TestDate testdate = new TestDate();
testdate.setDate(2022,8,05);
testdate.printDate();
}
}
输出结果:
0-0-0
小tips:
局部变量在使用时必须要初始化,而成员变量可以不用
类的成员变量初始化的时候。有两种初始化方式:1.默认初始化。2.就地初始化
像上面直接创建三个成员变量这个就叫做默认初始话。默认初始化的值是各个类型的0值。和数组的默认初始化一样。
就地初始化就是在声明成员变量时,就直接给出了初始值。
这种输出结果说明调用了成员方法却没有给成员变量赋值,
该成员方法参数名和成员变量名相同,根据就近原则可知,是不参数值赋值给了参数值,并未对成员变量产生影响。
this引用定义和使用
我们要想解决此问题就要用到this应用。this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this的三种用法
- this.成员变量
- this.成员方法。访问成员方法
- this();构造方法。访问构造方法
public class TestDate {
public int year;
public int month;
public int day;
public void setDate(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
TestDate testdate = new TestDate();
testdate.setDate(2022,8,05);
testdate.printDate();
}
}
该程序能正常输出结果。
2022-8-5
除了函数参数的this ,建议都把this都写上。
那么在main方法中定义多个对象赋值并输出结果是什么呢?
public static void main(String[] args) {
TestDate testdate1 = new TestDate();
TestDate testdate2 = new TestDate();
TestDate testdate3 = new TestDate();
TestDate testdate4 = new TestDate();
testdate1.setDate(2022,8,05);
testdate2.setDate(2023,8,05);
testdate3.setDate(2024,8,05);
testdate4.setDate(2025,8,05);
testdate1.printDate();
testdate2.printDate();
testdate3.printDate();
testdate4.printDate();
}
输出结果:
2022-8-5
2023-8-5
2024-8-5
2025-8-5
说明哪个对象调用就是哪个对象的引用类型。
this只能在"成员方法"中使用。在"成员方法"中,this只能引用当前对象,不能再引用其他对象。
this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收。
构造方法
构造方法可以在实例化对象的过程中给成员变量赋值。
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。在没有给类设计构造方法的时候,编译器默认给类一个无参数的构造方法。
public class TestDate {
public int year;
public int month;
public int day;
public TestDate(){
System.out.println("无参数的构造函数");
}
public TestDate(int year,int month,int day){
System.out.println("有三个参数的构造函数");
this.setDate(year,month,day);
}
public void setDate(TestDate this ,int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(TestDate this){
System.out.println(this.year + "-" + this.month + "-" + this.day);
}
public static void main(String[] args) {
TestDate testdate = new TestDate();
testdate.setDate(2022,8,05);
testdate.printDate();
TestDate testdate2 = new TestDate(2022,8,6);
testdate2.printDate();
}
}
输出结果为:
无参数的构造函数
2022-8-5
有三个参数的构造函数
2022-8-6
输出结果也说明了,构造方法能够重载,并且构造方法名字与类名相同没有返回值
构造方法的特性:
- 名字必须与类名相同
- 没有返回值类型,设置为void也不行
- 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
- 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
- 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。
注意:一旦用户定义了构造类型,编译器则不再生成。
public class TestDate {
public int year;
public int month;
public int day;
public TestDate(int year,int month,int day){
System.out.println("有三个参数的构造函数");
this.setDate(year,month,day);
}
public void setDate(TestDate this ,int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(TestDate this){
System.out.println(this.year + "-" + this.month + "-" + this.day);
}
public static void main(String[] args) {
TestDate testdate = new TestDate();//error
testdate.setDate(2022,8,05);
testdate.printDate();
TestDate testdate2 = new TestDate(2022,8,6);
testdate2.printDate();
}
}
上述代码报错java: 无法将类 TestDate中的构造器 TestDate应用到给定类型;
是因为用户自己构造了构造方法,编译器便不再默认构造一个无参的构造方法,所以TestDate testdate = new TestDate();是错误的
构造方法中,可以通过this调用其他构造方法来简化代码
上述构造三个参数的构造方法时: this.setDate(year,month,day);简化了代码,还可以用this();构造方法。访问其他构造方法。
public class TestDate {
public int year;
public int month;
public int day;
public TestDate(){
this(2022,8,6);//this(...)必须是构造方法中第一条语句
System.out.println("无参数的构造函数");
}
public TestDate(int year,int month,int day){
System.out.println("有三个参数的构造函数");
this.setDate(year,month,day);
}
public void setDate(TestDate this ,int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(TestDate this){
System.out.println(this.year + "-" + this.month + "-" + this.day);
}
public static void main(String[] args) {
TestDate testdate = new TestDate();
testdate.printDate();
}
}
输出结果为;
有三个参数的构造函数
无参数的构造函数
2022-8-6
注意事项;
- this(…)必须是构造方法中第一条语句
- 不能形成环
会报错,因为这样会无休止的重复调用两个构造方法,Java语法不支持这样做。