java对象内存分配、可变参数、方法重载、this

目录

类与对象

访问修饰符 

对象内存分配机制 

成员方法

简单的小练习 

 成员方法传参机制

 克隆对象

方法递归调用

方法重载

可变参数 

作用域 

构造器/方法(constructor)

对象创建的流程分析(面试题)

this

练习题 


类与对象

  1. 类就相当于是我们自定义的一个数据类型
  2. 类是属性和行为的集合
  3. 类创建的对象就是一个具体的实例(实例化)
  4. 创建对象:类名 对象名 = new 类名();
  5. 访问对象属性:对象名.属性名
  6. 属性也叫成员变量
  7. 属性可以是基本数据类型也可以是数组
  8. 属性如果不赋值,有默认值(见java入门第五天数组细节)
  9. Cat cat1 = new Cat();cat1是对象名,new Cat()创建的对象空间才是真正的对象
import java.util.*;
public class Object01{
    public static void main(String []args) {
		Cat cat1 = new Cat();
		cat1.name = "大橘";
		cat1.age = 2;
		cat1.color = "橘色";
		Cat cat2 = new Cat();
		cat2.name = "牛奶";
		cat2.age = 1;
		cat2.color = "黑白";
		System.out.println("第1只猫的名字:" + cat1.name + " 年龄:" + cat1.age + " 颜色:" + cat1.color);
		System.out.println("第2只猫的名字:" + cat2.name + " 年龄:" + cat2.age + " 颜色:" + cat2.color);
	}
}

class Cat{
    String name;
    int age;
    String color;
}

 对象创建

  1. 直接创建 Cat cat = new Cat();
  2. 先声明再创建 Cat cat;  cat = new Cat();

访问修饰符 

访问修饰符 属性类型 属性名;

  1. public 
  2. protected
  3. 默认(不写)
  4. private 

对象内存分配机制 

看看下段代码会输出什么

Person a = new Person();
a.age = 10;
a.name = "小明";
Person b = a;
Syatem.out.println(b.name);  //小明
b.age = 20;
b = null;
Syatem.out.println(a.age);  //20 b不指向与a相同的空间了,b指向空
Syatem.out.println(b.age);  //抛出异常,b已经不是一个对象了

class Person{
    int age;
    String name;
}


成员方法

  • 访问修饰符 返回值类型 方法名(参数列表){

        语句;

        return 返回值;

}

  • 调用方法:对象名.方法名(参数);
  1. 当程序执行到方法时,就会开辟一个独立的栈空间
  2. 方法执行完毕,或者执行到return,就会返回到调用方法的地方,开辟的栈空间被释放
  3. 返回后继续执行代码
  • 返回数据类型
  1. 一个方法最多有一个返回值
  2. 返回类型可以是基本类型也可以是引用类型
  3. 如果方法是void,方法体中可以没有return语句
  • 细节
  1. 方法体里不能有方法,即方法不能嵌套定义
  2. 同一个类中的方法直接调用,不需要创建对象

简单的小练习 

import java.util.*;
public class MethodExercise01{
    public static void main(String []args) {
		Scanner scanner = new Scanner(System.in);
		AA a = new AA();
		System.out.println("请输入一个数,判断是否为奇数:");
		int n = scanner.nextInt();
		if(a.isOdd(n)){
			System.out.println(n + "是奇数");
		}else{
			System.out.println(n + "不是奇数");
		}
		System.out.println("请输入要打印的图形的行数、列数以及符号:");
		int row = scanner.nextInt();
		int col = scanner.nextInt();
		char c = scanner.next().charAt(0);
		a.print(row,col,c);
	}
}

class AA{
	public boolean isOdd(int n){
		return n%2 == 1;
	}
	public void print(int row,int col,char c){
		for(int i = 0; i < row; i++){
			for(int j = 0 ; j < col; j++){
				System.out.print(c);
			}
			System.out.println();
		}
	}
}

 成员方法传参机制

  1. 基本数据类型,传递的是值拷贝,形参的任何改变不影响实参
  2. 引用数据类型,传递的是地址,可以通过形参影响实参

public class MethodExercise01{
    public static void main(String[] args){
        Person p = new Person();
        p.age = 20;
        B b = new B();
        System.out.println(p.age); //20
        
        //思考会输出什么?
        b.test1(p);
        System.out.println(p.age); //24
        
        //再来,思考一下
        b.test2(p);
        System.out.println(p.age); //24 这里形参p指向了空,实参p还是指向那块空间
        
        //这个呢?
        b.test3(p);
        System.out.println(p.age); //24 
    }
}

class Person{
    int age;
    String name;
}

class B{
    public void test1(Person p){
        p.age = 24;
    }
    public void test2(Person p){
        p = null;
    }
    public void test3(Person p){
        p = new Person(); //形参p指向一块新空间,与实参p所指空间不同了
        p.age = 36;
    }
}

 克隆对象

编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。

要求:得到的新对象和原来的对象是相互独立的,只是属性相同

public class MethodExercise02{
    public static void main(String[] args){
        Person p = new Person();
        p.age = 20;
		p.name = "小明";
        MyTools tools = new MyTools();
		Person p2 = tools.copyPerson(p);

        //可以通过对象比较看看是否为一个对象
		System.out.println(p == p2);
        p2.name = "小明2号";
		System.out.println("p的名字:" + p.name + "\t年龄:" + p.age);
		System.out.println("p2的名字:" + p2.name + "\t年龄:" + p2.age);
        
    }
}

class Person{
    int age;
    String name;
}

class MyTools{
	public Person copyPerson(Person p){
		Person p2 = new Person();
		p2.age = p.age;
		p2.name = p.name;
		return p2;
	}
}

方法递归调用

(1)猴子吃桃子问题

有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个!
以后每天猴子都吃其中的一半,然后再多吃一个。
当第10天时想再吃,发现只有一个桃子了。
问:最初有多少个桃子? 

/*
day10: 1
day9: (1+1)*2=4
day8: (4+1)*2=10
...
dayn:  (day(n+1)+1)*2
*/

public class Recursion01{
	public static void main(String[] args){
		T t = new T();
		int day = 1;
		int n = t.peach(day);
		System.out.println("最初有" + n + "个桃子");
	}
}

class T{
	public int peach(int day){
		if(day == 10){
			return 1;
		}else if(day >= 1 || day < 10){
			return (peach(day+1)+1)*2;
		}else{
			System.out.println("输入的day应该在1-10");
			return -1;
		}
	}
}

(2)迷宫问题 

用二维数组表示(8,7)的迷宫

从(1,1)走到(6,5)

红色表示障碍物,不能走 

public class MiGong{
	public static void main(String[] args){
		int[][] map = new int[8][7];
		//0表示可以走,1表示障碍物
		for(int i = 0; i < 7; i++){
			map[0][i] = 1;
			map[7][i] = 1;
		}
		for(int i = 1; i < 7; i++){
			map[i][0] = 1;
			map[i][6] = 1;
		}
		map[3][1] = 1;
		map[3][2] = 1;
        map[2][2] = 1;
		
		T t = new T();
		t.findWay(map, 1, 1);
		
		System.out.println("找路情况如下:");
		for(int i = 0; i < 8; i++){
			for(int j = 0; j < 7; j++){
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
	}
}

class T{
	//0表示可以走,1表示障碍物,2表示走过且可以走,3表示走过但走不通
	//找路策略:下-右-上-左
	public boolean findWay(int[][] map, int i, int j){
		if(map[6][5] == 2){
			return true;
		}else{
			if(map[i][j] == 0){  
				map[i][j] = 2;
				if(findWay(map, i+1, j)){
					return true;
				}else if(findWay(map, i, j+1)){
					return true;
				}else if(findWay(map, i-1, j)){
					return true;
				}else if(findWay(map, i, j-1)){
					return true;
				}else{
                    map[i][j] = 3;
					return false;
				}
				
			}else{   //map[i][j]=1为障碍物不能走,map[i][j]=2以及走过了
				return false;
			}
		}
	}
}

 (3)汉诺塔问题 

三根柱子有n个圆盘,大圆盘始终在下,小圆盘始终在上,从一根柱子全部移动到另一根柱子,一次只能移一个盘子,要怎么移动?

public class HanoiTower{
	public static void main(String[] args){
		Tower t = new Tower();
		int num = 2;
		t.move(num, 'A', 'B', 'C');
	}
}

class Tower{
	//num表示要移动的个数,a,b,c表示柱子
	public void move(int num, char a, char b, char c){
		if(num == 1){
			System.out.println(a + "-->" + c);
		}else{
			//有多个盘,看成2个
			move(num-1, a, c, b);
			move(1, a, b, c);
			move(num-1, b, a, c);
		}
	}
}

方法重载

  1. 允许同一个类中,允许多个同名方法存在
  2. 要求形参列表不一样(形参类型或个数,参数名无要求)
  3.  返回类型无要求

answer


可变参数 

  1. java允许将多个同名、同功能但参数个数不同的方法封装成一个方法
  2. 访问修饰符 返回类型 方法名(形参类型...形参名) 

细节

  1. 可变参数的实参可以是0-多个
  2. 可变参数的实参可以是数组
  3. 可变参数的本质就是数组
  4. 可变参数可以和普通类型的参数放一起,但要求可变参数在最后
    public void func(String str, int...nums){
    }

  5. 一个形参列表最多只能有一个可变参数

作用域 

  • java中主要的变量是属性(全局/成员变量)和局部变量
  • 局部变量:除了属性之外的变量(一般是在成员方法中定义的变量)
  • 属性的作用域为整个类
  • 局部变量的作用域为定义它的代码块中

  • 全局变量可以不赋值直接使用,因为属性有默认值
  • 局部变量必须赋值后才能使用,局部变量没有默认值

 

  • 属性和局部变量可以重名,使用时遵循就近原则
  • 属性可以加访问修饰符,局部变量不能加修饰符

  • 同一成员方法中的局部变量不能重名
  •  属性生命周期较长随对象创建而创建,随对象销毁而销毁;局部变量随代码块执行而创建,随代码块结束而销毁
  • 属性可以在本类直接使用,或者在其他类通过对象调用
  • 局部变量只能在本类使用

构造器/方法(constructor)

  • 想在创建对象时,直接给属性赋值,就可以用构造器
  • 是类的一种特殊方法,完成对新对象的初始化
  • 基本语法:【修饰符】方法名(形参列表){ 方法体; }
  1. 构造器的修饰符可以默认,也可以是public protected private
  2. 构造器没有返回值
  3. 方法名 和 类名 必须一样
  4. 参数列表 和 成员方法 一样的规则
  5. 构造器的调用由系统完成

 

 细节

  1. 一个类可以有多个构造器(构造器重载)
  2. 构造器名和类名相同
  3. 构造器没有返回值
  4. 构造器完成的是对象初始化,不是创建
  5. 构造器调用由系统完成
  6. 若未定义构造器,系统会给类自动生成一个默认无参构造器
  7. 一旦定义了自己的构造器,默认的构造器就被覆盖了,即不能再使用默认的无参构造器

javap反编译可以看到默认构造器 (由.class文件得到.java文件) 


对象创建的流程分析(面试题)

首先在方法区加载Person类信息;接着在堆中开辟一个对象空间,age是int型默认为0,name是String默认是null;然后看到age显性初始化为90;然后系统调用构造器,name赋值为“小倩”,在方法区常量池中为“小倩”开辟一个空间, name指向“小倩”,age赋值为20;最后在栈中p指向堆中的对象空间。


this

  1. this可以用来访问本类的属性、方法和构造器
  2. this用于区分当前类的属性和局部变量
  3. this相当于类的隐藏属性
  4. 哪个对象调用this,this就代表哪个对象 
  5. 访问构造器:this(参数列表),只能在另一个构造器中使用,且必须位于第一句
  6. this只能在类定义的方法中使用,不能在类外部使用


练习题 

public class Homework01{
	public static void main(String[] args){
		A01 a = new A01();
		double arr[] = {12.0, -1.5, 6.8, 9.9, 100.1};
		System.out.println(a.max(arr));
	}
}

class A01{
	public double max(double...nums){
		//求double数组的最大值
        int max = 0;
		for(int i = 1; i < nums.length; i++){
			if(nums[max] < nums[i]){
				max = i;
			}
		}
		return nums[max];
	}
}
public class Homework02{
	public static void main(String[] args){
		A02 a2 = new A02();
		String strs[] = {"hello", "happy", "love", "lucky", "persistence"};
		System.out.println(a2.find("persistence",strs));
		System.out.println(a2.find("love",strs));
		System.out.println(a2.find("haha",strs));
	}
}

class A02{
	public int find(String x,String...strs){
		//String数组查找元素返回索引
		for(int i = 0; i < strs.length; i++){
			if(strs[i].equals(x)){
				return i;
			}
		}
		return -1;
	}
}
public class Homework03{
	public static void main(String[] args){
		Book HongLouMeng = new Book("红楼梦", 62.1);
		HongLouMeng.updatePrice();
		HongLouMeng.info();
	}
}

class Book{
	String title;
	double price;
	public Book(String title, double price){
		this.title = title;
		this.price = price;
	}
	public void updatePrice(){
		//更改价格
		if(this.price > 150){
			this.price = price;
		}else if(this.price > 100){
			this.price = price;
		}else{
			return;
		}
	}
	public void info(){
		System.out.println("书名:" + this.title + ",价格:" + this.price);
	}
}

 

public class Homework04{
	public static void main(String[] args){
		A03 a3 = new A03();
		int[] arr = {10, 20, 26, 42, 100, -1};
		int[] newArr = a3.copyArr(arr);
		System.out.println("arr是否等于newArr?" + (arr == newArr));
		System.out.println("arr:");
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println("\nnewArr:");
		for(int i = 0; i < newArr.length; i++){
			System.out.print(newArr[i] + " ");
		}
	}
}

class A03{
	public int[] copyArr(int[] arr1){
		int[] arr2 = new int[arr1.length];
		for(int i = 0; i < arr2.length; i++){
			arr2[i] = arr1[i];
		}
		return arr2;
	}
}
public class Homework05{
	public static void main(String[] args){
		Circle circle = new Circle(1);
		circle.perimeter();
		circle.area();
	}
}

class Circle{
	double radius;
	public Circle(double radius){
		this.radius = radius;
	}
	public void perimeter(){
		//打印圆周长
		System.out.println("圆的周长:" + (2*Math.PI*radius));
	}
	public void area(){
		//打印圆面积
		System.out.println("圆的面积:" + (Math.PI*radius*radius));
	}
}
public class Homework06{
	public static void main(String[] args){	
		Cale c = new Cale(12, 6);
		c.sum();
		c.minus();
		c.mul();
		c.div();
        System.out.println("===========");
        Cale c2 = new Cale(99, 0);
        c2.sum();
		c2.minus();
		c2.mul();
		c2.div();
	}
}

class Cale{
	double a;
	double b;
	public Cale(double a, double b){
		this.a = a;
		this.b = b;
	}
	public void sum(){
		System.out.println(a + " + " + b + " = " + (a + b));
	}
	public void minus(){
		System.out.println(a + " - " + b + " = " + (a-b));
	}
	public void mul(){
		System.out.println(a + " * " + b + " = " + (a*b));
	}
	public void div(){
		if(b == 0){
			System.out.println("除数不能为0");
		}else{
			System.out.println(a + " / " + b + " = " + (a/b));
		}
	}
	
}

 

public class Homework07{
	public static void main(String[] args){
		Dog doggy = new Dog("圆圆", "白色", 2);
		doggy.info();
	}
}

class Dog{
	String name;
	String color;
	int age;
	public Dog(String name, String color, int age){
		this.name = name;
		this.color = color;
		this.age = age;
	}
	public void info(){
		System.out.println("狗狗的名字:" + name + " 颜色:" + color + " 年龄:" + age);
	}
}

 ⭐⭐

8、answer:输出10、9、10

t1对象的count属性最后为11

 


 

public class Homework09{
	public static void main(String[] args){
		Music music = new Music("雨天", 3.14);
		music.play();
		music.getInfo();
	}
}

class Music{
	String name;
	double times;
	public Music(String name, double times){
		this.name = name;
		this.times = times;
	}
	public void play(){
		System.out.println("你能体谅 我有雨天~");
	}
	public void getInfo(){
		System.out.println("音乐名:" + name + " 时长:" + times);
	}
}

 


11. answer: public double method(double d1, double d2){...}

class Employee{
	String name;
	char gender;
	int age;
	String occupation;
	double sal;
	public Employee(String name, char gender, int age){
		this.name = name;
		this.gender = gender;
		this.age = age;
	}
	public Employee(String occupation, double sal){
		this.occupation = occupation;
		this.sal = sal;
	}
	public Employee(String name, char gender, int age, String occupation, double sal){
		this(name, gender, age);
		this.occupation = occupation;
		this.sal = sal;
	}
}

public class Homework13{
	public static void main(String[] args){
		PassObject p = new PassObject();
		Circle c = new Circle();
		p.printAreas(c, 5);
	}
}

class Circle{
	double radius;
	public double findArea(){
		return Math.PI*radius*radius;
	}
	public void updateRadius(double radius){
		this.radius = radius;
	}
}

class PassObject{
	public void printAreas(Circle c, int times){
		System.out.println("Radiius\t面积");
		for(int i = 1; i <= times; i++){
			c.updateRadius(i);
			System.out.println(i + "\t" + c.findArea());
		}
	}
}

扩展题可以尝试自己做做~ 

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lili_1i1i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值