方法重载(OverLoad)
java 中允许同一个类中,多个同名方法的存在,但要求形参列表不同
比如: System.out.println(); out 是 PrintStream 类型
好处:
- 减轻起名的麻烦
- 减轻记名的麻烦
快速入门
public class OverLoad01 {
public static void main(String[] args) {
MyCaculator c = new MyCaculator();
System.out.println(c.calculate(1, 2));
System.out.println(c.calculate(1, 2.5));
System.out.println(c.calculate(1.5, 2));
System.out.println(c.calculate(1, 2, 3));
}
}
class MyCaculator {
public int calculate(int n1, int n2){
return n1 + n2;
}
public double calculate(int n1, double n2){
return n1 + n2;
}
public double calculate(double n1, int n2){
return n1 + n2;
}
public int calculate(int n1, int n2, int n3){
return n1 + n2 + n3;
}
}
细节
- 方法名要相同
- 形参列表:必须不同(形参类型或个数或顺序,至少有一个不同,形参名无要求)
- 返回类型无要求
可变参数
java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
细节
- 可变参数的实参可以为 0 个或任意多个
- 可变参数的实参可以为数组
- 可变参数的本质就是数组
- 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
- 一个形参列表中只能出现一个可变参数
练习
public class VarParameterExercise {
public static void main(String[] args) {
HspMethod method = new HspMethod();
System.out.println(method.showScore("bbchen", 100, 80)); // 2门
System.out.println(method.showScore("Tim", 90, 100, 80)); // 3门
System.out.println(method.showScore("Eason", 90, 100, 80, 70.5, 100)); //5门
}
}
class HspMethod {
// 传入可变参数 scores
public String showScore(String name, double... scores){
double totalScore = 0;
for(int i = 0; i < scores.length; i++){
totalScore += scores[i]; // 当作数组处理求和
}
String ret = name + " " + scores.length
+ "门课的总分为:" + totalScore;
return ret;
}
}
作用域 (scope)
- 在 java 编程中,主要的变量就是属性(成员变量)和局部变量
- 局部变量一般是指在成员方法中定义的变量
作用域分类:
全局变量:也就是属性
局部变量:除了属性之外的其他变量,作用域为定义它的代码块中
- 全局变量(属性)可以不赋值,直接使用,因为有默认值;局部变量必须赋值后才能使用,因为有默认值
细节
- 属性和局部变量可以重名,访问时遵循就近原则
- 在同一个作用域中,比如同一个成员方法中,两个局部变量不能重名
- 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。
作用域范围不同
全局变量(属性):可以被本类使用,或者被其他类使用(通过对象调用)。两种调用方法:
局部变量:只能在本类的对应方法中使用
修饰符不同
全局变量(属性)可以加修饰符(public protected private..)
局部变量不可以加修饰符
构造方法/构造器(constructor)
构造方法又称构造器,是类的一种特殊方法,它的主要作用是完成对象的初始化。
基本语法
[修饰符] 方法名(形参列表){
方法体;
}
说明:
- 构造器的修饰符可以默认,也可以是 public protected private
- 构造器没有返回值
- 方法名和类名必须一样
- 参数列表 和 成员方法一样的规则
- 构造器的调用由系统完成
快速入门
public class Constructor01 {
public static void main(String[] args) {
// new一个对象时,直接通过构造器指定名字和年龄
Person p1 = new Person("Smith", 45);
System.out.println("p1对象的name=" + p1.name);
System.out.println("p1对象的age=" + p1.age);
}
}
class Person{
String name;
int age;
// 构造器
// 1.没有返回值,也不能写void
// 2.构造器的名称和类Person一样
// 3.构造器形参列表的规则和成员方法一致
public Person(String pName, int pAge){
System.out.println("构造器被调用,完成对象的属性初始化");
name = pName;
age = pAge;
}
}
细节
- 一个类可以定义多个不同的构造器,即构造器重载
- 构造器名和类名要相同
- 构造器没有返回值
- 构造器是完成对象的初始化,不是创建对象
- 在创建对象时,系统自动调用该类的构造方法
public class ConstructorDetail {
public static void main(String[] args) {
// new一个对象时,直接通过构造器指定名字和年龄
Person p1 = new Person("Smith", 45); // 第一个构造器
System.out.println("p1对象的name=" + p1.name);
System.out.println("p1对象的age=" + p1.age);
Person p2 = new Person("Jim"); // 第二个构造器
System.out.println("p2对象的name=" + p2.name);
}
}
class Person{
String name;
int age;
// 第一个构造器
public Person(String pName, int pAge){
name = pName;
age = pAge;
}
// 第二个构造器,只初始化姓名
public Person(String pName){
name = pName;
}
}
如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫做默认构造器),使用 javap 指令反编译查看
- 一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能再使用默认的无参构造器,除非显式地定义一下:Dog(){}
对象创建的流程分析
对象(在堆中)数据先进行默认初始化,再进行显性初始化,最后构造器的初始化
- 加载Person类信息(Person.class),只会加载一次
- 在堆中分配空间(地址)
- 完成对象初始化 =》三步
- 对象在堆中的地址,返回给p(p是对象名,即对象的引用)
public class ConstructorExercise {
public static void main(String[] args) {
// new一个对象时,直接通过构造器指定名字和年龄
Person p1 = new Person(); // 第一个构造器
System.out.println("p2对象的name=" + p1.name); // null
// 构造器初始化总是最后执行,因此 p1.name 并非80而是18
System.out.println("p1对象的age=" + p1.age); // 18
Person p2 = new Person("Jim", 17); // 第二个构造器
System.out.println("p2对象的name=" + p2.name);
System.out.println("p2对象age=" + p2.age);
}
}
class Person{
// 第一个构造器,无参
public Person(){
age = 18;
}
// 第二个构造器,初始化 name 和 age
public Person(String pName, int pAge){
name = pName;
age = pAge;
}
String name;
int age = 80;
}
this 关键字
引出
java 虚拟机会给每个对象分配 this,代表当前对象。使用 this 解决上图的变量命名问题。
public Dog(String name, int age){
// this.name 就是当前对象的属性 name
this.name = name;
// this.age 就是当前对象的属性 age
this.age = age;
}
理解 this
简单的说,哪个对象调用,this 就代表哪个对象
细节
- this 可以用来访问本类的属性、方法、构造器
- this 用于区分当前类的属性和局部变量
- 访问成员方法的语法:this.方法名(参数列表)
访问构造器语法:this(参数列表);
注意只能在构造器中使用(即只能在构造器中访问另一个构造器)
注意this(参数列表)必须放置在第一条语句
- this 不能在类定义的外部使用,只能在类定义的方法中使用
public class This01 {
public static void main(String[] args) {
Person p1 = new Person("Tim", 18);
Person p2 = new Person("Smith", 20);
Person p3 = new Person("Tim", 18);
System.out.println("p1 p2比较结果:" + p1.compareTo(p2));
System.out.println("p1 p3比较结果:" + p1.compareTo(p3));
}
}
class Person{
String name;
int age;
// 构造器
public Person(String name, int age){
this.name = name;
this.age = age;
}
public boolean compareTo(Person p){
// 姓名年龄是否一样
// if(this.name.equals(p.name) && this.age == p.age){
// return true;
// }
// else{
// return false;
// }
return this.name.equals(p.name) && this.age == p.age;
}
}
评论