Java笔记6 面向对象编程(初级)

6.1 类与对象

  • 类就是数据类型
  • 对象就是一个具体的实例
  • 属性(成员变量)不赋值的话,有默认值,规则和数组一致

6.2 对象在内存中的存在形式

在这里插入图片描述

6.3 类和对象的内存分配机制

在这里插入图片描述

在这里插入图片描述

6.4 方法的调用机制原理

在这里插入图片描述

6.5 成员方法传参机制

6.5.1 基本数据类型的传参机制

  • 基本数据类型,传递的是值(拷贝一份),形参的改变不影响实参
  • 在这里插入图片描述

6.5.2 引用数据类型的传参机制

  • 引用数据类型,传递的是地址,可以通过形参影响实参

  • 在这里插入图片描述

  • p=null;p=new Pewson();是把方法开辟的栈空间中的地址p改变,主栈中的地址p和地址指向的内存不受影响在这里插入图片描述

6.5.3 练习

编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象, 注意要求得到新对象和原来的 对象是两个独立的对象,只是他们的属性相同

6.6 方法递归调用

6.6.1 递归案例

public class Recursion01 {
    //编写一个 main 方法
    public static void main(String[] args) {
        T t1 = new T();
        t1.test(4);//输出什么? n=2 n=3 n=4
        int res = t1.factorial(5);
        System.out.println("5 的阶乘 res =" + res);
    }
}
class T {
    //打印问题
    public void test(int n) {
        if (n > 2) {
            test(n - 1);
        }
        System.out.println("n=" + n);
	}
    //factorial 阶乘
    public int factorial(int n) {
        if (n == 1) {
            return 1;
        } else {
            return factorial(n - 1) * n;
		}
	}
}
6.6.1.1 打印问题

在这里插入图片描述

6.6.1.2 阶乘问题

在这里插入图片描述

6.6.2 递归重要规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  2. 方法的局部变量是独立的,不会相互影响,比如n变量
  3. 如果方法中使用的是引用类型变量(比如数组、对象),就会共享该引用类型的数据
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError,死龟了
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时但方法执行完毕或者返回时,该方法也就执行完毕,将栈空间的控制权、数据的分配权释放

6.6.3 练习

在这里插入图片描述

  1. public class RecursionExer01 {
        public static void main(String[] args) {
            T t1 = new T();
            System.out.println(t1.fibonacci(7));
        }
    }
    
    class T {
        /*
        n = 1 斐波那契数 -> 1
        n = 2 斐波那契数 -> 1
        n >= 3 斐波那契数 -> 前两个数的和
         */
        public int fibonacci(int n) {
            if(n >= 1){
                if(n == 1 || n == 2)
                    return 1;
                else
                    return fibonacci(n-1) + fibonacci(n-2);
            }else{
                System.out.println("请输入大于一的整数!");
                return -1;
            }
            
        }
    }
    
  2. /*
    猴子每次吃一半多一个桃子,第十天剩一个,原本有几个
    反推:
    day = 10 时,有1个桃子
    day = 9 时,有(day10+1)* 2 = 4
    day = 8 时,有(day9+1)* 2 = 10
    ......
     */
    public class RecursionExer02 {
        public static void main(String[] args) {
            T t1 = new T();
            System.out.println(t1.eatPeach(8));
        }
    }
    class T {
        public int eatPeach(int day) {
            if(day == 10) {
                return 1;
            } else if (day >= 1 && day <= 9){
                return (eatPeach(day + 1) + 1) * 2;
            } else {
                System.out.println("输入1-10");
                return -1;
                
            }
        }
    }
    

6.6.4 迷宫

见代码MiGong.java

6.6.5 汉诺塔

6.6.6 八皇后

6.7 方法重载(overload)

同名不同参(个数、类型、顺序),返回类型无要求

public int calculate(int n1, int n2) {
	System.out.println("calculate(int n1, int n2) 被调用");
	return n1 + n2;
}
//没有构成方法重载, 仍然是错误的,因为是方法的重复定义
//public void calculate(int n1, int n2) {
//	System.out.println("calculate(int n1, int n2) 被调用");
//	int res = n1 + n2;
//}

6.8 可变参数

6.8.1 概念用法

java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。

public int sum(int... nums) {
	//System.out.println("接收的参数个数=" + nums.length);
	int res = 0;
	for(int i = 0; i < nums.length; i++) {
		res += nums[i];
	}
	return res;
}

int res = sum(1, 2);
int res = sum(1, 2, 3);

6.8.2 使用细节

  1. 可变参数的实参可以是0或者任意多个
  2. 可变参数的实参可以是数组
  3. 可变参数的本质就是数组
  4. 可变参数可以和普通类型的参数一起放在参数列表,但必须保证可变参数在最后
  5. 一个参数列表中只能出现一个可变参数

6.8.3 练习

在这里插入图片描述

public class VarParameterExercise {
    public static void main(String[] args) {
        HspMethod hsp = new HspMethod();
        System.out.println(hsp.showScore("李明", 85, 90, 94));
        System.out.println(hsp.showScore("张华", 70, 85, 75, 60));
    }
}

class HspMethod {
    public String showScore(String name, double... scores) {
        double sum = 0;
        for (int i = 0; i < scores.length; i++) {
            sum += scores[i];
        }
        return name + scores.length + "门课成绩的总分为:" + sum;
    }
}

6.9 作用域

6.9.1 基本使用

  1. 在Java编程中,主要的变量就是属性(成员变量)和局部变量
  2. 局部变量一般是值成员方法中定义的变量,还有就是代码块中定义的变量
  3. 作用域的分类
    1. 全局变量:也就是属性,作用域为整个类体(成员方法可以直接使用)
    2. 局部变量:属性之外的其他变量,作用域为定义它的代码块中
  4. 全局变量可以不赋值,直接使用,因为有默认值;局部变量必须赋值后,才能使用,因为没有默认值

6.9.2 使用细节

  1. 属性和局部变量可以重名,访问时遵循就近原则
  2. 在同一个作用域中,两个局部变量不能同名
  3. 属性生命周期长,伴随着对象的创建而创建,伴随着对象的销毁而销毁;局部变量生命周期短,伴随着它的代码块执行而创建,伴随着代码块的结束而销毁,即在一次方法调用过程中
  4. 作用范围不同
    1. 全局变量/属性:可以被本类使用,或者其他类使用(通过对象调用)
    2. 局部变量:只能在本类中对应的方法中使用
  5. 修饰符不同
    1. 全局变量/属性可以加修饰符
    2. 局部变量不可以加修饰符

6.10 构造方法/构造器

完成对对象的初始化

6.10.1 基本语法

[修饰符] 方法名 (形参列表) {
    方法体;
}

6.10.2 使用细节

  1. 构造器的修饰符可以是默认、public、protected或者private
  2. 构造器没有返回值
  3. 方法名和类名一致(大小写)
  4. 参数列表和成员方法规则一致(可以无参、多参或者全参)
  5. 构造器的调用由系统完成,在创建对象时,系统会自动的调用该类的构造器完成对象的初始化
  6. 没有定义构造器时,系统会自动生成一个无参构造器
  7. 定义自己的构造器后,默认的构造器被覆盖了,就不能再使用默认的无参构造器,除非显式地定义一下,即:Dog(){}

6.11 对象创建的流程分析

class Person {
    int age = 90;
    String name;
    Person(String n, int a) {
        name = n;
        age = a;
    }
}

Person p = new Person("小倩", 20);

流程:

  1. 加载Person类信息(Person.class),只会加载一次
  2. 在堆中分配空间(地址)
  3. 完成对象初始化
    1. 默认初始化,规则和数组一致
    2. 显式初始化,age = 90,name = null
    3. 构造器初始化,age = 20,name = “小倩”
  4. 把对象在堆中的地址,返回给p(p是对象名,也可以理解成对象的引用)

在这里插入图片描述

6.12 this关键字

  1. 哪个对象调用,this就代表哪个对象

  2. this关键字可以用来访问本类的属性、方法、构造器

    1. 访问成员方法的语法:this.方法名(参数列表);

    2. 访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一条语句)

      1. class T {
            private String name;
            private int age;
            //this访问构造器举例
            public T() {
                this("jack", 100);
                System.out.println("T()构造器被调用");
            }
            public T(String name, int age) {
                System.out.println("T(String name, int age)构造器被调用");
                
            }
            //this访问成员方法举例
            public void f1() {
                System.out.println("f1()方法···");
            }
            public void f2() {
                System.out.println("f2()方法···");
                f1();	//调用本类的f1的第一种方法
                this.f1();	//调用本类的f1的第二种方法,有区别
            }
        }
        
  3. this用于区分当前类的属性和局部变量

  4. this不能在类定义的外部使用,只能在类定义的方法中使用

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值