类的成员包括属性和方法,也称作成员变量和成员方法。
1.成员方法
1.1.方法重载
方法重载是OOP中的一个重要概念,而实际开发中经常用的方法重载。
1.1.1.方法重载的定义
方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数类型或参数个数或参数顺序。即:在同一个类中,同名不同参,与返回值无关。
public class Student{
public void play(){
}
public int play(int time){
return 0;
}
}
1.1.2.方法重载的调用
方法重载在调用时,根据实参与形参在类型、个数、顺序一一匹配的规则调用。即:方法重载根据参数匹配原则进行调用。
public class Student{
public void play(){
System.out.println("方法一");
}
public int play(int time){
System.out.println("方法二");
return 0;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.play(); //调用的是第一个方法
Student s2 = new Student();
s2.play(1); //调用的是第二个方法
}
}
运行结果:
方法一
方法二
2.什么是构造方法
2.1.什么是构造方法
构造方法也叫构造函数,或者叫构造器
在java中,当类创建一个对象时会自动调用该类的构造方法,构造方法分为默认构造方法和自定义的构造方法。
构造方法的语法格式:
[访问修饰符] 方法名([参数列表]){
//方法体的代码
}
特点:
1.构造方法的方法名必须与类名相同
2.构造方法没有返回值,也不写void
示例:
public class Student {
//构造方法
Student(){
}
}
注意:下面这个方法是构造方法吗?
public class Student {
void Student(){//普通方法,可有对象调用
}
void play(){
}
}
答:不是,第2行的Student()方法前面添加了void,因此不是构造方法,此时它是一个普通的方法。与play方法一样。可以使用实例化后对象调用Student()方法。
不推荐把普通方法名称定义为与类名相同。
2.2.构造方法的作用
构造方法的作用为成员变量初始化(为对象的属性初始化)。
2.2.1.默认构造函数
一个类如果没有显示的定义构造函数,那么这个类默认具有无参的构造函数。
默认构造函数为对象的属性赋默认值。
class Student {
String name;
int score;
String no;
public void play(){
System.out.printf("我的名字是%s,我的成绩是%d,我的学号是%s",this.name,this.score,this.no);
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 =new Student();
s1.play();
}
}
运行结果:
我的名字是null,我的成绩是0,我的学号是null
为什么输出的是null,0,null?
分析:因为本例中没有定义构造函数,系统会自动添加一个默认构造函数,默认构造函数是无参的,会为所有的属性赋默认值,因此name是null,score是0,no是null。
2.2.2.自定义的构造函数
如果显示的定义了构造函数,那么默认构造函数就没有啦。
class Student {
String name;
int score;
String no;
//显示定义构造函数,此时默认构造函数就没有了
Student(){
}
}
2.3.构造方法的调用
构造方法是在实例化对象时调用的。并且实例化时传递的参数必须有构造方法的参数一致。
class Student {
String name;
int score;
String no;
/**
* 有两个参数的构造方法
* @param name1
* @param score1
*/
Student(String name1,int score1){
name= name1;
score= score1;
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 =new Student("haha",76);//调用student类的构造方法,为name和score属性初始化,no为默认值null
}
}
构造方法不允许通过对象名调用。例如下面的调用是错误的:
public static void main(String[] args) {
Student s1 =new Student("haha",76);
s1.Student("haha",88);//错误的,对象名不允许调用构造函数
}
2.4.构造方法的重载
class Student {
String name;
int score;
String no;
//第1种构造方法的重载
Student(String name1,int score1){
name= name1;
score= score1;
}
//第2种构造方法的重载
Student(String name1, int score1, String no1) {
name = name1;
score = score1;
no = no1;
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 =new Student("haha",76);//调用第1种构造方法的重载
Student s2 =new Student("yaya",67,"111");//调用第2种构造方法的重载
}
}
采坑:
这个实例化为什么报错?
class Student {
String name;
int score;
String no;
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("haha",76); //报错,为什么?
}
}
分析:因为new 类时必须调用构造方法,而第8行有两个参数haha和76,因此会调用有两个参数的构造,但是类中没有定义有两个参数的构造,因此报错。
3.this关键字
this关键字是对一个对象的默认引用,即:this代表的是当前正在运行的对象。
class Student {
String name;
int score;
String no;
Student(String name,int score){
name= name;
score= score;
}
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",name,score,no);
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("haha",76);
s1.sayHello();
}
}
运行结果:
我是null,我的成绩是0,我的学号是null
分析原因:为什么是null,0,null?
看构造函数
Student(String name,int score){
name= name; //name的值赋给了name,前面的name是谁?后面的name是谁?前后的name都是方法参数name
score= score; //score的值赋给了score,前面的score是谁?后面的score是谁?前后的score都是方法参数score
}
原因是
1.前后的name都是方法参数name
2.前后的score都是方法参数score
在类中,如果类的属性名和方法内部的局部变量同名时,那么在方法内部使用的是局部变量,也就是变量使用遵循就近原则。
解决方法:
String name;
int score;
String no;
Student(String name,int score){
//this代表正在运行的对象,当执行第16行代码时,调用了构造函数,此时this代表第16行的s1
this.name= name; //this.name指的是对象的属性,name是指方法的参数。
this.score= score; //this.score指的是对象的属性,score是指方法的参数。
}
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",this.name,this.score,this.no);
}
}
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("haha",76);
s1.sayHello();
}
}
运行结果:
我是haha,我的成绩是76,我的学号是null
3.1.什么时候可以省略this
在非static方法内部使用属性,可以省略。
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",this.name,this.score,this.no);
}
public void sayHello(){
System.out.printf("我是%s,我的成绩是%d,我的学号是%s",name,score,no);
}
两种结果相同
4.成员变量
成员变量是类的属性,直接定义在类内,方法的外部的变量。
例如:
class Student {
String name;
int score;
String no;
}
4.局部变量
局部变量是定义在方法内的变量
例如:
public void sayHello(){
int height = 20;//局部变量
}
成员变量和局部变量的区别
-
作用域不同
- 成员变量作用域:整个类
- 局部变量的作用域:方法内
-
初始值不同
- 成员变量由构造函数初始化的
- 局部变量需要手动初始化
在同一个方法中不允许有同名的局部变量,在不同的方法中可以有同名的局部变量。
局部变量可以和成员变量名相同,并且在使用时局部变量有更高的优先级。