方法
构造方法
格式
- 构造方法名与类名完全相同并且没有返回值类型,void 都不能有
- 构造方法可以没有参数
class 类名{
类名(形参列表){
构造方法体;
}
}
class Person{
//无参构造方法
Person(){
//Person类中的构造方法;
}
//有参构造方法
Person(String str,int i){
//Person类中的构造方法;
name = str;
age = i;
}
public static void main(String[] args){
Person p = new Person(); //调用无参的构造方法
Person p1 = new Person("张三",30); //调用有形参的构造方法
}
}
默认构造方法
- 当一个类中没有定义任何构造方法时,编译器会自动添加一个无参空构造方法
- 若类中出现了构造方法,则编译器不再提供任何形式的构造方法
构造方法作用
- 使用new关键字创建对象时会自动调用构造方法实现成员变量初始化 工作
方法重载
- 若方法名称相同,参数列表不同,这样的方法之间构成重载关系(Overload)
重载的体现形式
- 参数的个数 不同
- 参数的类型 不同
- 参数的顺序 不同
- 与返回值类型无关
- 与形参变量名无关
-
判断方法能否构成重载的核心: 调用方法时能否加以区分
-
建议 返回值 类型最好相同
public class Person{
//重载的使用
//无参方法
void overLoadFunction() {
System.out.println("fun()");
}
//形参为 int 体现在方法参数个数不同
void overLoadFunction(int i) {
System.out.println("fun(int)");
}
//形参为 int double 方法参数个数不同
void overLoadFunction(int i, double d) {
System.out.println("fun(int,double)");
}
//形参为 int int 方法参数类型不同
void overLoadFunction(int i, int j) {
System.out.println("fun(int,int)");
}
//形参为 double int 方法参数顺序不同
void overLoadFunction(double d, int i) {
System.out.println("fun(double,int)");
}
// erro 与方法形参变量名称无关
// void overLoadFunction(double d, int i) {
// System.out.println("fun(double,int)");
// }
// erro 与方法返回值类型无关
// int overLoadFunction(double d, int i) {
// System.out.println("fun(double,int)");
// return 0;
// }
public static void main(String[] args){
//方法的重载测试
Person p = new Person();
p.overLoadFunction();
p.overLoadFunction(12);
p.overLoadFunction(12, 30.15);
p.overLoadFunction(12, 15);
p.overLoadFunction(3.156, 15);
}
}
运行结果:
重载的意义
- 对于调用者来说,只需记住一个方法名就可以调用各种不同的版本,来实现不同的功能
- 官方println() 示例:
- 官方println() 示例:
this关键字
基本概念
- 若在构造方法中出现this关键字,则代表当前正在构造的对象
- 若在成员方法中出现this关键字,则代表当前正在调用的对象
- this关键字本质上就是当前类类型的引用变量
public class Person{
Person(){
System.out.prirntln("构造方法中的this为: "+this);
}
void show(){
System.out.println("show方法中的this为: "+this);
}
public static void main(String[] args){
Person p = new Person();
p.show();
System.out.println("main中的 p 为: " + p);
}
}
运行结果:
工作原理
- 在构造方法中和成员方法中访问成员变量时,编译器会加上*this.*的前缀 *this.*相当于汉语 我的
- 当不同的对象调用同一个方法时,由于调用方法的对象不同导致this关键字不同,从而*this.*方式访问的结果也不同
- this 关键字本质上就是本类类型的一个引用变量
使用方式
-
当局部变量名与成员变量名相同时,在方法体中会优先使用局部变量(就近原则)
- 若希望使用成员变量,则需要在成员变量的前面加上*this.*的前缀,明确要求该变量时成员变量
-
this关键字 作为方法的返回值
-
在构造方法的第一行可以使用 ***this()***或者 this(参数列表) 的方式来调用本类中的其它构造方法
- 在无参构造方法中添加 this(“无参中调用有参”); 则无法在有参构造方法中添加 this() 无参构造方法【二者不可同存】
class Boy { String name; //无参构造方法 Boy() { this("无参中调用有参"); //调用本类中的有参构造方法 System.out.println("无参构造方法"); } //有参构造方法 Boy(String name) { //this(); //调用本类中的无参构造方法 System.out.println("有参构造方法"); this.name = name; } void show() { System.out.println("我的名字是: " + name); } public static void main(String[] args){ Boy b = new Boy(); b.show(); System.out.println("************************************"); Boy b2 = new Boy("法外张三"); b2.show(); } }
运行结果:
引用变量的注意事项
- 引用类型变量用于存放对象的地址,可以给引用类型赋值 null 表示不指向任何对象
- 当某个引用类型变量为null时无法对 对象 实施访问(因为没有指向任何对象);此时,如果通过引用访问成员变量或调用方法,会产生 空指针 异常
- 错误说明: NullPointerException 空指针
实践出真理
递归的概念
- 递归本质就是指在方法体的内部 直接或间接调用 当前方法自身的形式
递归的主要事项
- 使用递归必须有递归的规律以及退出条件
- 使用递归必须使得问题简单化而不是复杂化
- 若递归影响到程序的执行性能,则使用 递推 取代
1.计算阶乘
//方式一: for循环的
int factorial_For(int n) {
int sum = 1;
for (int i = 1; i <= n; i++) {
sum *= i;
}
return sum;
}
//方式二: 递归的方式
int factorial(int n) {
if (1 == n) {
return 1;
}
return n * factorial(n - 1);
}
2.费氏数列
- 费氏数列: 1 1 2 3 5 8 13 21 …
//递归的方式 !!耗时!!不推荐使用
int feiShi(int n) {
if (1 == n || 2 == n)
return 1;
return feiShi(n - 1) + feiShi(n - 2);
}
//递推的方式
int feiShi_For(int n) {
int fee = 0;
int a = 1;
int b = 1;
for (int i = 3; i <= n; i++) {
fee = a + b;
a = b;
b = fee;
}
return fee;
}
构造块和静态代码块
构造块
- 在类体中直接使用 {} 括起来的代码块
- 每创建一个对象都会执行一次构造块
静态代码块
- 使用static关键字修饰的代码块
- 静态代码块随着类加载时执行一次
public class BlockTest{
//执行顺序在构造方法前
//当需要在执行构造方法体之前做一部分准备工作时,则将准备工作的相关代码写在构造块中
//比如:对成员变量进行统一初始化操作
{
System.out.println("!构造块!");
}
//静态代码块
//随着类的加载而准备就绪,先于构造块
//需要在执行代码块之前随着类的加载做一些准备工作时,则编写代码到静态代码块中
//比如: 加载数据库的驱动包
static {
System.out.println("!静态代码块!");
}
//自定义构造方法
public BlockTest() {
System.out.println("-构造方法体-");
}
public static void main(String[] args){
BlockTest bt = new BlockTest();
BlockTest bt2 = new BlockTest();
}
}
运行结果:
单例模式
实现流程
- 私有化构造方法,使用private关键字修饰
- 声明本类类型的引用指向本类类型的对象,并使用 private static 关键字共同修饰
- 提供公有的get方法负责将对象返回出去,并使用 public static 关键字共同修饰
实现方式
1.饿汉式 【推荐】
//Singleton类
public calss Singleton{
//按照封装时三步走
//2. 声明本类型的引用指向本类类型的对象,使用 private static 关键字共同修饰
private static Singleton sin = new Singleton();
//1. 私有化构造方法
private Singleton() {
}
//3. 提供公有的get方法负责将对象返回出去,使用 public static 关键字共同修饰
public static Singleton getInstance() {
return sin;
}
}
2.懒汉式
//Singleton类
public calss Singleton{
//2. 声明本类型的引用指向本类类型的对象,使用 private static 关键字共同修饰
private static Singleton sin = null;
//按照封装时三步走
//1. 私有化构造方法
private Singleton() {
}
//3. 提供公有的get方法负责将对象返回出去,使用 public static 关键字共同修饰
public static Singleton getInstance() {
if(null == sin){
sin = new Singleton();
}
return sin;
}
}