java基础(day08)-面向对象
目录
面向对象
介绍
定义class
Constructor 构造方法
默认构造方法
多个构造方法
构造代码块
作用:
小结
附:
成员变量和局部变量
面向对象
介绍
面向对象编程,是一种通过对象的方式,把现实世界映射到计算机模型的一种编程方法。
class和instance
所以,只要理解了class
和instance
的概念,基本上就明白了什么是面向对象编程。
类 : class
是一种对象模版,它定义了如何创建实例,因此,class
本身就是一种数据类型.
对象:而instance
是对象实例,instance
是根据class
创建的实例,可以创建多个instance
,每个instance
类型相同,但各自属性可能不相同.
注意:
a.new关键字用于创建一个对象的实例.
b.使用 . 来访问对象中的属性和方法.
c.同一个类可以创建多个实例.
定义class
声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, Java 使用关键字 class 来声明类。我们来看以下简单的声明一个类。
// 创建类
public class <class_name>{field;//成员属性method;//成员方法
}// 实例化对象
<class_name> <对象名> = new <class_name>();修饰符 class 类名{//修饰符此处用:public//class: 修饰类的关键字//类名:标识符,大驼峰命名法//1、里面可以写成员变量——属性(对类的信息静态的信息描述)修饰符 变量类型 变量名;修饰符:public变量类型:可以是任意类型变量名: 标识符//2.里面可以写功能(对类的动态信息或者功能的描述)修饰符 返回值类型 方法名(参数){修饰符:public如果没有返回值,返回值的位置写void如果有返回值,则必须写return对应类型的返回值}}
创建实例
Person ming = new Person();
上述代码创建了一个Person
类型的实例,并通过变量ming
指向它。
注意区分Person ming
是定义Person
类型的变量ming
,而new Person()
是创建Person
实例。
有了指向这个实例的变量,我们就可以通过这个变量来操作实例。访问实例变量可以用变量.字段
,例如:
ming.name = "Xiao Ming"; // 对字段name赋值
ming.age = 12; // 对字段age赋值
System.out.println(ming.name); // 访问字段namePerson hong = new Person();
hong.name = "Xiao Hong";
hong.age = 15;┌──────────────────┐
ming ──────>│Person instance │├──────────────────┤│name = "Xiao Ming"││age = 12 │└──────────────────┘┌──────────────────┐
hong ──────>│Person instance │├──────────────────┤│name = "Xiao Hong"││age = 15 │└──────────────────┘
注:⚠️ 一个Java
源文件可以包含多个类的定义,但只能定义一个public
类,且public
类名必须与文件名一致。如果要定义多个public
类,必须拆到多个Java
源文件中。
Constructor 构造方法
初始化对象实例需要3
行代码,而且,如果忘了调用setName()
或者setAge()
,那么这个实例,所持有的值或许就是不正确的。这时,我们就需要通过构造方法,创建对象实例时就把内部字段全部初始化为合适的值。
创建实例的时候,实际上是通过构造方法来初始化实例的。我们先来定义一个构造方法,能在创建Person
实例的时候,一次性传入name
和age
,完成初始化:
public class Main {public static void main(String[] args) {Person p = new Person("Xiao Ming", 15);System.out.println(p.getName());System.out.println(p.getAge());}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public int getAge() {return this.age;}
}
注:由于构造方法比较特殊,所以构造方法的名称就是类名。构造方法的参数没有限制,在方法内部,也可以编写任意语句。但是,和普通方法相比,构造方法没有返回值(也没有void
),调用构造方法,必须用new
操作符。
默认构造方法
class Person {public Person() {}
}
注:如果我们自定义了一个构造方法,那么,编译器就不再自动创建默认构造方法:
public class Main {public static void main(String[] args) {Person p = new Person(); // 编译错误:找不到这个构造方法}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public int getAge() {return this.age;}
}
如果,既要能使用带参数的构造方法,又想保留不带参数的构造方法,那么只能把两个构造方法全部都定义出来:
public class Main {public static void main(String[] args) {Person p1 = new Person("Xiao Ming", 15); // 既可以调用带参数的构造方法Person p2 = new Person(); // 也可以调用无参数构造方法}
}class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return this.name;}public int getAge() {return this.age;}
}
没有在构造方法中初始化字段时,引用类型的字段默认是null
,数值类型的字段用默认值,int
类型默认值是0
,布尔类型默认值是false
class Person {
private String name; // 默认初始化为null
private int age; // 默认初始化为0
private boolean isVip; // 默认初始化为false
public Person() {
}
}
多个构造方法
class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person(String name) {this.name = name;this.age = 12;}public Person() {}
}
- 如果调用
new Person("Xiao Ming", 20);
,会自动匹配到构造方法public Person(String, int)
- 如果调用
new Person("Xiao Ming");
,会自动匹配到构造方法public Person(String)
- 如果调用
new Person();
,会自动匹配到构造方法public Person()
构造代码块
在Java
的类中使用{}
声明的构造代码块,构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优先于构造函数执行。
public class CodeBlock {// 后续学习static{System.out.println("静态代码块");}// 构造代码块{System.out.println("构造代码块");}
}
注意:静态代码块,随着类的加载而加载,只执行一次
作用:
和构造函数的作用类似,都能对对象进行初始化,并且只要创建一个对象,构造代码块都会执行一次。但是反过来,构造函数则不一定每个对象建立时都执行(多个构造函数情况下,建立对象时传入的参数不同则初始化使用对应的构造函数)。利用每次创建对象的时候都会提前调用一次构造代码块特性,我们可以实现诸如统计创建对象的次数等类似功能。
小结
- 实例在创建时通过
new
操作符会调用其对应的构造方法,构造方法用于初始化实例 - 没有定义构造方法时,编译器会自动创建一个默认的无参数构造方法
- 可以定义多个构造方法,编译器根据参数自动判断
- 可以在一个构造方法内部调用另一个构造方法,便于代码复用
附:
成员变量和局部变量
package test;/** 成员变量 定义在类内方法外 有默认值,同数组相同 在类内部可以使用* 局部变量 定义在方法内 必须要先声明后赋值再使用 在方法内使用* 成员变量随着对象的创建而产生,随着垃圾回收而消亡,声明周期长* 局部变量随着方法的入栈而产生,随着方法的出栈而消亡,生命周期短*/
//成员变量私有化,提供getset方法。
public class Person {//属性:定义的位置,类内,方法的外面//public 公共的public String name;//操作成员变量的时候可能会有非法操作//可以不让外部直接操作成员变量,将成员变量私有化,使用private修饰成员变量//提供setXXX赋值,有参数无返回值//提供getXXX取值,有返回值无参数private int age;// 无参构造方法public Person(){// this()表示调用构造方法,在进行使用this()// 必须要放在构造方法内的第一行this("张三",20);System.out.println("创建person对象");}// 有参构造方法public Person(String name,int age){this.age = age;this.name = name;}public int getAge(){return age;}//主要给成员变量age进行赋值,在赋值的过程中会检验参数的合法性//赋值有参数,无返回值//当局部变量和成员变量发生重名,优先使用局部。//此时可以使用this关键字,强制声明使用的变量为成员变量。用法:this.变量名public void setAge(int age){if(age>=0 && age<=120){this.age = age;}else{System.out.println("你传入的年龄有误");}}public void eat(String food){System.out.println(name+"喜欢吃"+food);}public String showMessage(){return "person{name: "+name+" age: "+age+'}';}
}