zoukankan      html  css  js  c++  java
  • 8Java类与对象

    类与对象

    • 引入类
    // 类与对象
    // 一个程序就是一个世界,有很多事物(对象[属性, 行为])
    
    public class Object01{
    
    	public static void main(String[] args) {
    		
    		/*
    		张老太养了两只猫,一只猫的名字叫小白,今年三岁,白色
    		一只叫小花,今年100岁,请编写一个程序,当用户输入小猫的名字时,
    		就显示这个猫的年龄,名字,颜色,如果用户的输入小猫名有误
    		显示 张老太没有这只猫
    		 */
    		
    		// 单独变量来解决 => 不利于数据的管理(把一只猫的数据拆解)
    		// 第一只猫的信息
    		String cat1Name = "小白";
    		int cat1Age = 3;
    		String cat1Color = "白色";
    
    		// 第二只猫的信息
    		String cat2Name = "小花";
    		int cat2Age = 100;
    		String cat2Color = "花色";
    
    
    		// 数组  ===> 数据类型不能体现出来,
    		// 只能通过下标获取信息,造成变量名字和内容对应关系不明确
    		// 不能体现猫的行为
    		// 第一只猫的信息
    		// String[] cat1 = {"小白", "3", "白色"};
    		// String[] cat2 = {"小花", "100", "花色"};
    
    
    		// 现有技术的缺点
    		// 不利于数据的管理
    		// 效率低,引出我们新的知识点,类和对象
    		// java的设计者引入类与对象(OOP),根本原因是现有的技术不能完美的解决新的需求
    		// 
    		// 
    		// 
    		// 使用OOP面向对象解决
    		// 实例化一只猫【创建一个猫对象】
    		// 1.new Cat()  创建一只猫
    		// 2.Cat cat1 = new Cat();把创建的猫赋值给cat1
    		Cat cat1 = new Cat();
    		cat1.name = "小白";
    		cat1.age = 3;
    		cat1.color = "白色";
    		cat1.weight = 10;
    
    		// 创建第二只猫对象
    		Cat cat2 = new Cat();
    		cat2.name = "小花";
    		cat2.age = 100;
    		cat2.color = "花色";
    		cat2.weight = 23.9;
    
    	
    		// 怎么使用,怎么访问对象的属性
    		System.out.println("第一只猫的信息" + cat1.name + " " + cat1.age + " " + cat1.color + " " + cat1.weight);
    		System.out.println("第一只猫的信息" + cat2.name + " " + cat2.age + " " + cat2.color + " " + cat2.weight);
    
    
    	}
    }
    
    // 使用面向对象的方式解决养猫问题
    // 定义一个猫类 Cat - > 自定义数据类型
    // 
    class Cat{
    
    	// 属性
    	String name;
    	int age;
    	String color;
    	double weight;
    }
    
    
    • 类在内存中的存在形式(重要)
    
    public class Object02{
    
    	public static void main(String[] args) {
    		
    	}
    }
    
    class Car{
    	String name; // 属性 成员变量 字段  field
    	double price;
    	String color;
    	String[] master; // 属性可以是基本数据类型,也可以是引用类型
    }
    
    • 属性的注意事项
    1. 属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;
      这里老师简单的介绍访问修饰符: 控制属性的访问范围 有四种访问修饰符 public, proctected, 默认, private ,后面我会详细介绍
    2. 属性的定义类型可以为任意类型,包含基本类型或引用类型
    3. 属性如果不赋值,有默认值,规则和数组一致。具体说: int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000, boolean false,String null
    public class Properties{
    	public static void main(String[] args) {
    		
    		// 创建对象
    		// p1 是对象名(对象引用
    		// new Perso() 创建的对象空间才是真正的对象
    		Person p1 = new Person();
    
    		// 对象的属性默认值,遵守数据的规则
    		System.out.println("当前人的信息");
    		System.out.println("age=" + p1.age + " name = " + p1.name + " sal=" + p1.sal + " isPass " + p1.isPass);
    	}
    }
    
    class Person{
    
    	int age;
    	String name;
    	double sal;
    	boolean isPass;
    }
    
    • 类的内存结构
    1. 栈: 一般存放基本数据类型(局部变量)
    2. 堆: 存放对象(Cat cat , 数组等)
    3. 方法区:常量池(常量,比如字符串), 类加载信息
    4. 示意图 [Cat (name, age, price)]
    
    public class Object03{
    	public static void main(String[] args) {
    		
    		Person p1 = new Person();
    		p1.age = 10;
    		p1.name = "小明";
    
    		Person p2 = p1;
    
    		p2.age = 80;
    		System.out.println(p1.age); // 10
    
    	}
    }
    
    class Person{
    	String name;
    	int age;
    
    }
    

    成员方法

    • 成员方法入门
    
    public class Method01{
    
    	public static void main(String[] args) {
    		// 方法写好了,如果不去调用,不会输出
    		// 如何使用方法,先创建一个对象,然后调用方法即可
    		Person p1 = new Person();
    		p1.speak(); // 调用方法
    		p1.cal01();
    		p1.cal02(5);
    		p1.cal02(100);
    
    		// 调用getSum方法,同时num1,num2
    		// 把方法 getSum 返回的值赋给变量 returnRes
    		int returnRes = p1.getSum(10, 20); // 
    		System.out.println("getSum 方法返回的值:" + returnRes);
    
    
    	}
    }
    
    class Person{
    	String name;
    	int age;
    
    	// 方法,成员方法
    	// 输出我是一个好人
    	// 1.public 表示方法是公开的
    	// 2. void 表示方法没有返回值
    	// 3. speak(),speak就是方法的名称,()形参列表,当前没有任何值在里面
    	// 4.{}方法体,可以写我们要执行的代码
    	// 
    	public void speak(){
    		System.out.println("我是一个好人");
    	}
    
    
    	public void cal01(){
    		// 循环完成
    		int sum = 0;
    		for(int i = 1; i <= 1000; i++){
    			sum += i;
    		}
    		System.out.println("cal01计算结果:"  + sum);
    	}
    
    	// 接受一个参数n, 计算1 + 2 + ... + n
    	// 形参列表,当前有个形参n,形参就是形式参数,可以接收用户的输入
    	
    	public void cal02(int n){
    		int sum = 0;
    
    		for(int i = 1; i <= n; i++){
    			sum += i;
    
    		}
    		System.out.println("cal02计算结果:" + sum);
    
    	}
    	// 添加getSum方法,可以计算两个数的和
    	// 1.public 表示方法是公开的
    	// 2. int 表示返回一个int值
    	// 3.(int num1, int num2) 形参列表,2个形参
    	// 4.return res 表示把res的值返回
    	public int getSum(int num1, int num2){
    		int result = num1 + num2;
    
    		return result;
    	}
    
    }
    
    • 方法的内存调用机制
    • 提高了代码的复用性,方法的最大优势,就是实现一个模块,可以多次复用
    • 可以将实现的细节封装起来,然后共其他用户调用即可
    public class Method02{
    
    	public static void main(String[] args) {
    		
    		// 遍历一个二维数组,输出数组的各个元素值
    		
    		int[][] map = {{0, 0, 1}, {1, 1, 1}, {1, 2, 3}};
    
    		// for(int i = 0; i < map.length; i++){
    		// 	for(int j = 0; j < map[i].length; j++){
    		// 		System.out.print(map[i][j] + " ");
    		// 	}
    
    		// 	System.out.println();
    		// }
    
    
    		// // 要求再次遍历这个map数组
    		// for(int i = 0; i < map.length; i++){
    		// 	for(int j = 0; j < map[i].length; j++){
    		// 		System.out.print(map[i][j] + " ");
    		// 	}
    
    		// 	System.out.println();
    		// }
    
    		// // 再次遍历,在复制一次
    		// for(int i = 0; i < map.length; i++){
    		// 	for(int j = 0; j < map[i].length; j++){
    		// 		System.out.print(map[i][j] + " ");
    		// 	}
    
    		// 	System.out.println();
    		// }
    		// 
    		// 使用方法进行输入
    		myTools tool =  new myTools();
    		tool.printArray(map);
    	}
    }
    
    // 把输入的功能,写入到类的方法中,然后调用这个方法即可
    class myTools{
    	// 接受一个二维数组
    	// 
    	public void printArray(int[][] map){
    		// 对传入的map数组进行遍历
    		for(int i = 0; i < map.length; i++){
    			for(int j = 0; j < map[i].length; j++){
    				System.out.print(map[i][j] + " ");
    			}
    
    			System.out.println();
    		}
    
    	}
    
    }
    
    • 成员方法的定义
      public 返回数据类型 方法名(形参){
      语句;
      返回值
      }

    成员方法注意事项

    1. 访问控制符,作用是控制方法使用的范围,默认有四种(public protected, 默认,private)
    2. 一个方法最多有一个返回值
    1. 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
    2. 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为 return 值; 而且要求返回值类型必须和 return 的 值类型一致或兼容
    3. 如果方法是 void,则方法体中可以没有 return 语句,或者 只写 return ;
    public class MethodDetail{
    	public static void main(String[] args) {
    		
    
    		// 1个方法最多有一个返回值,思考如何返回多个值,数组
    		// 2.返回类型可以为任何类型,包含基本类型和引用类型,数组,对象
    		// 3.如果方法要求有返回值类型,则必须有return值
    		// 而且要求return的值必须与return的值类型一致或者兼容
    		// 
    		// 4.如果是void,可以不写return或者return ,不能写其他
    		AA a = new AA();
    
    		int[] res = a.getSumAndSub(1, 4);
    
    		double b = a.f1();
    		System.out.println("和=" + res[0]);
    		System.out.println("差=" + res[1]);
    	}
    }
    
    class AA{
    	public int[] getSumAndSub(int n1, int n2){
    		int[] resArr = new int[2];
    
    		resArr[0] = n1 + n2;
    		resArr[1] = n1 - n2;
    
    		return resArr;
    	}
    
    	public double f1(){
    
    		double d1 = 1.1 * 3;
    		int n = 100;
    		return n;
    	}
    }
    

    方法的注意细节

    • 同一个类的方法直接调用, 不需要创建对象
    • 不同类之间的方法调用,需要在该类创建一个新的对象,才能使用别的方法
    
     public class MethodDetail02{
    
     	public static void main(String[] args) {
     		A a = new A();
     		a.sayOk();
     		a.m1();
    
     	}
     }
    
     class A{
     	// 同一个类的方法直接调用, 不需要创建对象
     	// 
     	public void print(int n){
     		System.out.println("print方法被调用  n = " + n);
     	}
    
     	public void sayOk(){
     		print(10);
    
     		System.out.println("继续执行sayOk");
     	}
    
     	// 跨类中的A类调用B类方法:需要通过对象名进行调用
     	// 
     	public void m1(){
     		// 创建B对象
     		System.out.println("A类中的m1被调用");
     		B b = new B();
     		b.hi();
     		System.out.println("M1方法继续执行");
    
     	}
     }
    
     class B{
     	// 跨内的方法,需要创建方法
     	// 
     	public void hi(){
     		System.out.println("B类的hi方法执行");
     	}
     }
    
    • 练习1 返回一个数是否是奇数
    public class MethodEx01{
    
    	public static void main(String[] args) {
    		
    		// 
    		AA a = new AA();
    		boolean isRight = a.isOdd(5);
    		System.out.println("5是奇数?" + isRight);
    	}
    }
    
    
    class AA{
    	// 思路
    	// 1 方法的返回类型是 boolean
    	// 2 方法的名字是 isOdd
    	// 3 方法的形参是 int num
    	// 4 方法体进行判断
    	public boolean isOdd(int num){
    
    		// boolean isRight = false;
    		// if(n % 2 == 1){
    		// 	isRight = true;
    		// }
    		// return isRight;
    		// 
    		// return num % 2 != 0 ? true: false;
    		// 
    		return num % 2 != 0;
    
    	}
    }
    
    • 练习2 输出一个行, 列,字符,打印这些字符
    public class MethodEx01{
    
    	public static void main(String[] args) {
    		
    		// 
    		AA a = new AA();
    		boolean isRight = a.isOdd(5);
    		// System.out.println("5是奇数?" + isRight);
    		
    		// 调用方法
    		a.printChar(4, 5, '*');
    	}
    }
    
    
    class AA{
    	// 思路
    	// 1 方法的返回类型是 boolean
    	// 2 方法的名字是 isOdd
    	// 3 方法的形参是 int num
    	// 4 方法体进行判断
    	public boolean isOdd(int num){
    
    		// boolean isRight = false;
    		// if(n % 2 == 1){
    		// 	isRight = true;
    		// }
    		// return isRight;
    		// 
    		// return num % 2 != 0 ? true: false;
    		// 
    		return num % 2 != 0;
    
    	}
    
    	// 思路
    	// 1 没有返回值
    	// 2 参数是三个,一个是行,一个是列,一个是字符
    	// 3 打印二维数组的思想
    	
    	public void printChar(int row, int col, char chara){
    		for(int i = 0 ; i < row; i++){
    			for(int j=0; j < col; j++){
    				System.out.print(chara + " ");
    			}
    
    			System.out.println();
    		}
    	}
    
    }
    

    成员变量传参机制

    • 传入的是基本数据类型,不会改变数据
    
    public class MethodParameter01{
    	public static void main(String[] args) {
    		
    		int a = 10;
    		int b = 20;
    
    		// 创建AA对象
    		AA obj = new AA();
    		obj.swap(a, b); // 调用swap方法
    		System.out.println("a和b经过swap的值a=" + a + "\tb=" + b);
    	}
    }
    
    class AA{
    
    	public void swap(int a , int b){
    
    		System.out.println("a和b交换前的值a=" + a + "\tb=" + b);
    		// 完成a和b的交换
    		// 
    		int temp = a;
    		a = b;
    		b = temp;
    		System.out.println("a和b交换后的值a=" + a + "\tb=" + b);
    	}
    }
    
    • 传入的是引用数据类型
      传入的是引用类型,由于传入的是地址,所以引用数据类型会改变
    
    public class MethodParameter02{
    
    	public static void main(String[] args) {
    		B b = new B();
    		int[] arr01 = {1, 2, 3};
    		b.test100(arr01);
    
    		System.out.println("main中的arr数组");
    		for(int i= 0; i < arr01.length; i++){
    			System.out.print(arr01[i] + "\t");
    		}
    
    
    	}
    }
    
    class B{
    
    	// 接受一个数组,修改这个数组
    	public void test100(int[] arr){
    
    		arr[0] = 200;
    
    		// 遍历数组
    		System.out.println("类B中test100方法中");
    		for(int i= 0; i < arr.length; i++){
    			System.out.print(arr[i] + "\t");
    		}
    
    		
    	}
    }
    
    • 练习1,如何复制一个新的空间的类
    
    public class MethodEx02{
    
    	public static void main(String[] args) {
    		
    		//
    		Person p =  new Person();
    		p.name = "Tom";
    		p.age = 12;
    
    		MyTools tools =  new MyTools();
    
    		Person p2 = tools.copyPerson(p);
    
    		System.out.println("p2的name值:" + p2.name + " p2的age值:" + p2.age);
    		p2.name = "小明";
    		// 提示,可以通过hashCode看看对象是否是同一个
    		// 可以通过对象比较看看是否是同一个
    		System.out.println(p == p2);
    		System.out.println("p1.name = " + p.name);
    		
    	}
    }
    
    class Person{
    	String name;
    	int age;
    
    
    }
    
    class MyTools{
    
    	// 编写一个方法 copyPerson,可以复制一个 Person 对象,返回复制的对象。克隆对象, 
    	// 注意要求得到新对象和原来的 对象是两个独立的对象,只是他们的属性相同
    	// 思路
    	// 确定返回类型为Person
    	// 方法的形参也是 Person p
    	// 完成一个复制,创建一个新对象,并复制属性,返回即可
    	// 
    	// 
    	public Person copyPerson(Person p){
    		// 创建一个person对象
    		Person p2 = new Person();
    		p2.name = p.name;
    		p2.age = p.age;
    
    
    
    		return p2;
    	} 
    }
    

    递归方法

    递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂问题,同时可以让代码变 得简洁

    • 递归入门,递归适合逻辑清晰,能够通过不断迭代来减少问题规模的场景,比如
    • f(n) = f(n-1) + f(n-2)
    • 汉诺塔等
    
    public class Recursion01{
    	public static void main(String[] args) {
    		
    		T t1 = new T();
    		t1.test(4);
    	}
    }
    
    class T{
    
    	public void test(int n){
    		if (n > 2){
    			test(n-1);
    		}
    
    		System.out.println("n=" + n);
    	}
    }
    
    • 递归的联系,数据的阶乘
    
    public class Recursion01{
    	public static void main(String[] args) {
    		
    		T t1 = new T();
    		// t1.test(4);
    		int res = t1.factorial(5);
    		System.out.println("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;
    		}
    		return n* factorial(n-1);
    	}
    }
    

    递归的注意细节

    • 课堂练习1:求出斐波拉列数
    
    public class RecursionEx01{
    
    	public static void main(String[] args) {
    		T t1 = new T();
    
    		int res = t1.fibonacci(7);
    		System.out.println("当n=7是的斐波那契数:" + res);
    	}
    }
    
    class T{
    	/*
    		使用递归的方法求出斐波那契数列,1,1, 2, 3, 5, 8, 13, 给你一个整数n,求它的值是多少?
    
    		思路分析:  
    		n = 1  斐波那契是 1	       
    		n = 2 斐波那契是 1
    		n >= 3 斐波那契是 前面两个数的和
    		这里就是递归的思路,n = 7 ,我就需要得到前面两个数,我得到前面两个数,就需要得到前面两个数,直到第一个和第二个数
    
    
    	 */
    	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 猴子吃桃子问题,有一堆桃子,猴子第一天吃了一把,并多吃一个,每天都是这样,当到第10天,只剩下一个桃子,求最初多少个桃子
      这个重点是在在于前一天的桃子 = (后一天的桃子+1) * 2
    
    public class RecursionEx02{
    	public static void main(String[] args) {
    		
    		T t1 = new T();
    		int day = 0;
    		int peachNum = t1.peach(day);
    
    		System.out.println(day + "的桃子是" + peachNum);
    
    	}
    }
    
    class T{
    
    	/*
    	猴子吃桃子,每天吃了其中的一半,然后多吃一个,直到第十天,只剩下一个桃子
    	请问最初有几个桃子
    	思路分析:
    	逆推:
    	第十天  1个桃子
    	第九天 最初 4个 桃子  4/2-1
    	第八天 10 个桃子   10/2 -1
    	......
    	 */
    	
    	public int peach(int day){
    		if(day == 10){
    			return 1;
    		}
    		else if(day >=1  && day <= 9){
    			return (peach(day+1) + 1) * 2;
    		}
    		else{
    			System.out.println("day在1-10");
    			return -1;
    		}
    
    
    	}
    	
    	 
    }
    
    • 练习3 老鼠出迷宫问题
      很有意思的一个递归题,对后面数,图的算法理解很有帮助
    
    public class RecursionEx03{
    
    
    	public static void main(String[] args) {
    		// 思路
    		// 1.先创建迷宫,用二维数组表示, int[][] map = new int[8][7];
    		// 2.先规定map数组的元素:0表示可以走,1表示障碍物
    		int[][] map = new int[8][7];
    
    		// 3.将上下两行,左右两列都设置为1
    		// 也可以用两个for循环进行设置,更快一点
    		
    		for(int i = 0; i < map.length; i++){
    			for(int j = 0; j < map[i].length; j++){
    				if(i == 0 || i == map.length-1){
    					map[i][j] = 1;
    				}
    				else if (j == 0 || j == map[i].length-1){
    					map[i][j] = 1;
    				}
    
    			}
    		}
    		// map[2][1] = 1;
    		// map[2][2] = 1;
    		// map[1][2] = 1;
    		map[3][1] = 1;
    		map[3][2] = 1;
    
    		// 输出地图情况
    		System.out.println("=====地图=======");
    		for(int i = 0; i < map.length; i++){
    			for(int j=0; j <map[i].length; j++){
    				System.out.print(map[i][j] + " ");
    			}
    			System.out.println();
    		}
    
    		// 使用findway找路
    		MiGong t1 = new MiGong();
    		t1.findWay(map, 1, 1);
    
    		// 输出找路的情况
    		System.out.println("\n=====找路的情况=======");
    		for(int i = 0; i < map.length; i++){
    			for(int j=0; j <map[i].length; j++){
    				System.out.print(map[i][j] + " ");
    			}
    			System.out.println();
    		}
    
    
    
    	}
    
    }
    
    
    class MiGong{
    
    	/*
    	使用递归回溯的思想来解决老鼠出迷宫
    	1. findway专门找到迷宫的路径
    	2.找到,就返回true,找不到返回false
    	3.map就是二维数组,表示迷宫
    	4. i,j就是老鼠的位置,初始化的位置为(1,1),终点位置(6,5);
    	5.因为是递归找路,我们规定map数组各个值的含义,
    		0:表示可以走,1:表示障碍物,
    		2:表示可以走 3:表示走过但是不通
    	退出递归:
    	6.当走到终点(6,5) = 2 就说明找到通路,就可以退出递归,否则就继续找
    	7.先确定老鼠找路的策略 下->右->上->左
    
    
    
    	 */
    	public boolean findWay(int[][]map, int i, int j){
    
    		if(map[6][5] == 2){ // 说明已经找到
    			return true;
    		}
    		else{
    			if(map[i][j] == 0){ // 当前位置为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, 2, 3
    				return false;
    			}
    		}
    	} 
    
    }
    
    • 汉诺塔问题
      汉诺塔问题是递归的经典问题,对于每一个塔来说,只解决三步,
      把最后一个塔以上的所有塔借助第三个针移到第二个针上
      把最后的塔移动第三个针上
      把第二个针上的塔借助第一个针移到第三个针上
    
    public class HanoiTower{
    	public static void main(String[] args) {
    		
    		HanTower tower =  new HanTower();
    		tower.move(10, 'A', 'B', 'C');
    	}
    }
    
    
    class HanTower{
    
    	// 方法
    	// num 表示要移动的个数, a,b,c表示A塔,B塔,C塔
    	// 
    	// 
    	public void move(int num, char a, char b, char c){
    		// 如果只有一个盘
    		if(num == 1){
    			System.out.println(a + "->" + c);
    		}
    		else{
    			// 如果有多个盘,可以 看出两个,最下面的,和上面所有盘
    			// 1.先移动上面所有盘到 B, 借助c
    			move(num - 1, a, c, b);
    			// 2.把最下面的盘移动到c
    			System.out.println(a + "->" + c);
    			// 再把b塔的所有盘移动到c,借助a
    			move(num - 1, b, a, c);
    		}
    
    	}
    }
    

    方法重载

    Java允许在一个类中多个同名的方法存在,但是形不一致,根据形参的数量自动调取需要的方法

    
    public class OverLoad01{
    	public static void main(String[] args) {
    		
    		System.out.println(100);
    		System.out.println("hello world");
    		System.out.println('h');
    		System.out.println(true);
    	}
    }
    
    • 自己类中定义的重载
    
    public class OverLoad01{
    	public static void main(String[] args) {
    		
    		// System.out.println(100);
    		// System.out.println("hello world");
    		// System.out.println('h');
    		// System.out.println(true);
    		// 
    		MyCalculator mc = new MyCalculator();
    
    		System.out.println(mc.calculate(1, 2));
    		System.out.println(mc.calculate(1.2, 3.4));
    		System.out.println(mc.calculate(1, 2, 3));
    	}
    }
    
    class MyCalculator{
    
    	// 下面四个方法构成了重载
    	// 两个整数的和
    	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, double n2){
    		return n1 + n2;
    	}
    
    	public int calculate(int n1, int n2, int n3){
    		return n1 + n2 + n3;
    	}
    }
    
    • 方法重载的注意事项和使用细节
    1. 方法名要一样
    2. 形参必须不一样,比如类型或者数量
    3. 返回值没有要求,返回值类型不同不属于方法重载
    
    public class OverLoadEx01{
    	public static void main(String[] args) {
    		Methods m1 = new Methods();
    		m1.m(3);
    		m1.m(3, 4);
    		m1.m("hello");
    
    	}
    }
    
    class Methods{
    
    	public void m(int a){
    		System.out.println(a*a);
    	}
    
    	public void m(int a, int b){
    		System.out.println(a * b);
    	}
    
    	public void m(String s){
    		System.out.println(s);
    	}
    }
    
    • 练习2,利用重载完成对两个数的比较
    
    public class OverLoadEx02{
    	public static void main(String[] args) {
    		
    		Methods m1 = new Methods();
    		System.out.println(m1.max(4, 5));
    		System.out.println(m1.max(4.5, 6.7));
    		System.out.println(m1.max(7.8, 8.8, 10));
    		
    		
    	}
    
    }
    
    class Methods{
    
    	public int max(int a, int b){
    		if(a > b){
    			return a;
    		}
    		else{
    			return b;
    		}
    	}
    
    	public double max(double a, double b){
    		if(a > b){
    			return a;
    		}
    		else{
    			return b;
    		}
    	}
    
    	public double max(double a, double b, double c){
    		if(a > b){
    			if (a > c){
    				return a;
    			}
    			else{
    				return c;
    			}
    		}
    		else{
    			if(b > c){
    				return b;
    			}
    			else{
    				return c;
    			}
    		}
    	}
    
    }
    

    可变参数

    java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
    就可以通过可变参数实现

    
    public class VarParameter02{
    	public static void main(String[] args) {
    		
    		HspMethod m = new HspMethod();
    		m.sum();
    		System.out.println(m.sum(1, 3, 4));
    	}
    }
    
    
    class HspMethod{
    
    	// 计算多个可变参数的值
    	// 解读
    	// 1. int... 表示接受的可变参数,类型是int,可以接收多个int
    	// 2. 使用可变参数时,可以当做数组来使用,即 nums 可以当做数组
    	// 3. 遍历求和即可
    	// 
    	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;
    	}
    }
    
    
    • 可变参数的使用细节
    1. 可变参数的实参可以为数组
    2. 实参可以为0个或者多个
    3. 可变参数可以跟普通参数放在新参列表,但是必须保证可变参数放在最后
    4. 一个形参列表中,只能有一个可变参数
    
    public class VarParameterDetail{
    	public static void main(String[] args) {
    		// 细节:可变参数的实参可以为数组
    		int[] arr = {1, 2, 3};
    		T t1 = new T();
    		t1.f1(arr);
    
    	}
    }
    
    class T{
    	public void f1(int... nums){
    		System.out.println("长度=" + nums.length);
    	}
    
    	// 细节:可变参数可以跟普通参数放在新参列表,但是必须保证可变参数放在最后
    	
    	public void f2(String str, double... nums){
    		
    	}
    }
    
    • 练习01,利用可变参数完成多个数据的相加
    
    public class VarParameterEx01{
    	public static void main(String[] args) {
    		
    		HspMethod score =  new HspMethod();
    		String[] newInfo = score.showScore("jack", 1.2, 3.4, 6.7);
    
    		for(int i = 0; i < newInfo.length; i++){
    			System.out.print(newInfo[i] + " ");
    		}
    	}
    }
    
    class HspMethod{
    
    	public String[] showScore(String name, double... scores){
    
    		String[] info = new String[2];
    		info[0] = name;
    
    		double sum = 0;
    		for(int i = 0; i < scores.length; i++){
    			sum += scores[i];
    		}
    		info[1] = sum + " ";
    		return info;
    	}
    }
    

    作用域

    
    public class VarScope{
    	public static void main(String[] args) {
    		
    		Cat myCat = new Cat();
    		myCat.cry();
    
    	}
    
    }
    
    class Cat{
    	// 全局变量,也就是属性,作用域在整个Cat类,cry eat 等方法使用属性
    	// 
    	// 属性定义时,可以直接赋值
    	int age = 10;
    
    	// 全局变量可以不赋值,直接使用,因为有默认值
    	// 局部变量必须赋值后,才能使用,因为没有默认值
    	// 
    	double weight; // 默认值是0.0
    
    	public void cry(){
    		// 1.局部变量一般是在成员方法中定义的变量
    		// 2.这里的n和name都是局部变量
    		// 3.n和name的作用域都在cry方法中
    		// 
    		int n = 10;
    		String name = "jack";
    		double year;
    		System.out.println("在cry中使用属性age = " + age);
    		System.out.print(year); // 报错,没有初始化不能使用,但是如果只有变量,但是不使用,也不会报错
    
    
    	}
    
    	public void eat(){
    		System.out.println("在eat中使用属性age = " + age);
    	}
    	
    }
    
    • 作用域使用细节
    1. 就近原则
    2. 同一个作用域下的变量不能重名
    3. 局部变量的生命周期随着作用域的不同而不同,局部变量的生命周期较短
    4. 不同的方法可以调用
    
    public class VarScopeDetail{
    
    	public static void main(String[] args) {
    		Person p1 = new Person();
    		p1.say(); //方法结束后,name就销毁了,但是类还在,因此类中的全局变量还存在
    
    
    		T t1 = new T();
    		t1.test();
    	}
    }
    
    class T{
    
    	// 全局变量,可以在本类中使用,也可以在其他类使用,对象调用
    	public void test(){
    		Person p2 = new Person();
    		p2.say();
    		System.out.println(p2.name);
    	}
    }
    
    class Person{
    	String name = "jack";
    
    
    	public void say(){
    		// String name = "king";
    		System.out.println("say() name = " + name);
    	}
    }
    

    构造器

    1.构造器没有返回值,也不能写void
    2.构造器的名字和类名必须一致
    3.构造器形参列表,规则与成员方法一致

    
    public class Constructor{
    
    	public static void main(String[] args) {
    		// 当我们new一个对象,直接通过构造器指定名字和年龄
    		Person p1 = new Person("smith", 90);
    		System.out.println("p1的信息如下");
    		System.out.println("p1对象的name=" + p1.name);
    	}
    }
    
    class Person{
    
    	String name;
    	int age;
    	// 构造器
    	// 
    	// 1.构造器没有返回值,也不能写void
    	// 2.构造器的名字和类名必须一致
    	// 3.构造器形参列表,规则与成员方法一致
    	public Person(String pName, int pAge){
    		System.out.println("构造器被调用~~");
    		name = pName;
    		age = pAge;
    	}
    }
    
    • 构造器的使用细节
    1. 一个类可以有多个构造器,即构造器的重载
    2. 构造器名字必须跟类名一致
    3. 构造器没有返回值
    4. 构造器是完成对象的初始化,不是创建对象
    5. 创建对象时,系统会自动的创建该类的构造方法
    6. 如果程序员没有定义构造 ,系统会自动给类生成一个默认无参构造方法,也叫默认构造方法
    7. 一旦定义了自己的构造器,就覆盖了默认的构造器,就不能使用无参的方法,除非显示的定义一下

    
    public class ConstructorDetail{
    
    	public static void main(String[] args) {
    		// 当我们new一个对象,直接通过构造器指定名字和年龄
    		Person p1 = new Person("smith", 90);
    		Person p2 = new Person("king");
    		System.out.println("p1的信息如下");
    		System.out.println("p1对象的name=" + p1.name);
    		System.out.println("p2对象的name=" + p2.name);
    	}
    }
    
    class Person{
    
    	String name;
    	int age;
    	// 构造器
    	// 
    	// 1.构造器没有返回值,也不能写void
    	// 2.构造器的名字和类名必须一致
    	// 3.构造器形参列表,规则与成员方法一致
    	public Person(String pName, int pAge){
    		System.out.println("构造器被调用~~");
    		name = pName;
    		age = pAge;
    	}
    
    	public Person(String pName){
    		name = pName;
    	}
    }
    
    • 练习 ,构造器练习
    
    public class ConstructorEx01{
    
    	public static void main(String[] args) {
    		Person p1 = new Person();
    		System.out.println("输出所有人:" + p1.age);
    
    		Person p2 = new Person("jack", 199);
    		System.out.println("输出" + p2.name + "年龄:" + p2.age);
    	}
    }
    
    class Person{
    
    	String name;
    	int age;
    
    	public Person(){
    		age = 18;
    	}
    
    	public Person(String pName, int pAge){
    		name = pName;
    		age = pAge;
    	}
    }
    

    对象创建的流程分析


    this关键字

    • 什么是this?
      java虚拟机会给每个对象分配this,代表当前对象
      使用this解决变量命名问题
    
    public class This01{
    	public static void main(String[] args) {
    		
    		Dog dog1 = new Dog("tom", 12);
    		System.out.println("dog1的hashCode=" + dog1.hashCode());
    		dog1.info();
    
    		Dog dog2 = new Dog("jack", 6);
    		dog2.info();
    	}
    }
    
    class Dog{
    	String name;
    	int age;
    
    	// public Dog(String dName, int dAge){
    	// 	name = dName;
    	// 	age = dAge;
    	// }
    	// 如果我们构造器的形参,能够直接写成属性名就更好了
    	// 构造器的name是局部变量,age也是局部变量,而不是属性
    	// 
    	// ==> 引出this关键字来解决
    	public Dog(String name, int age){
    		// this.name 就是当前对象的属性
    		this.name = name;
    		this.age = age;
    		System.out.println("this.hashCode=" + this.hashCode());
    	}
    	
    
    	// 成员方法,输出属性的信息
    	public void info(){
    		System.out.println(name + "\t" + age + "\t");
    	}
    
    }
    

    this 是在创建对象的时候,this的地址与创建对象的地址是一致的
    this就是哪个对象调用,就是值哪个对象

    • this使用细节
    1. this 关键字可以用来访问本类的属性、方法、构造器
    2. this 用于区分当前类的属性和局部变量
    3. 访问成员方法的语法:this.方法名(参数列表)
    4. 访问构造器语法:this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一条语句)
    5. this 不能在类定义的外部使用,只能在类定义的方法中使用
    
    public class ThisDetail{
    	public static void main(String[] args) {
    		
    		// T t1 = new T();
    		// t1.f2();
    		T t2 = new T();
    		//this
    		t2.f1();
    
    
    	}
    }
    
    
    class T{
    	/*
    	细节,访问构造器语法,只能在构造器中使用,this(参数列表),且必须放在第一条
    	 */
    	
    	String name = "jack";
    	int age = 12;
    
    
    	public T (){
    		
    		// 访问这个构造器
    		this("jack", 100);
    		System.out.println("T() 构造器");
    	}
    
    	public T(String name, int age){
    		System.out.println("T(String, int) 构造器");
    	}
    	public void f1(){
    		// this("jack", 100);
    		String name = "jin";
    		System.out.println("f1方法");
    		System.out.println("name = " + name  + " age = " + age);
    		System.out.println("name = " + this.name  + " age = " + this.age);
    	}
    
    	public void f2(){
    		System.out.println("f2方法");
    		f1();
    		this.f1();
    	}
    }
    
    • this 课堂练习
      定义 Person 类,里面有 name、age 属性,并提供 compareTo 比较方法,用于判断是否和另一个人相等,提供测试类 TestPerson
      用于测试, 名字和年龄完全一样,就返回 true, 否则返回
    
    public class TestPerson{
    	public static void main(String[] args) {
    		Person p1 = new Person("小花", 12);
    		Person p2 = new Person("小白", 12);
    
    		System.out.println("是否一样" + p2.compareTo(p1));
    
    	}
    }
    
    class Person{
    	String name;
    	int age;
    
    	public Person(String name, int age){
    		this.name = name;
    		this.age = age;
    	}
    
    	public boolean compareTo(Person p1){
    		if(this.name.equals(p1.name) && this.age == p1.age){
    			return true;
    		}
    		else{
    			return false;
    		}
    	}
    
    }
    
    • 类的作业1,返回一个max的方法
    
    public class Homework01{
    	public static void main(String[] args) {
    		
    		A01 a01 = new A01();
    		double arr[] = {};
    		Double res = a01.max(arr);
    		System.out.println("arr的最大值是:" + a01.max(arr));
    	}
    }
    
    
    class A01{
    	/*
    	思路分析:
    	1.类名 A01
    	2.方法名 max
    	3.形参 double[]
    	4.返回值 double
    
    	先完成业务,然后在考虑代码的健壮性
    	 */
    	
    	public Double max(double[] arr){
    		// 保证arr至少有一个元素
    		// 
    		if(arr.length > 0){
    			double maxNum = arr[0];
    			for(int i = 1; i < arr.length; i++){
    				if(arr[i] > maxNum){
    					maxNum = arr[i];
    				}
    			}
    
    			return maxNum;
    		}
    		else{
    			return null;
    		}
    		
    	}	
    
    }
    
    • 作业2:返回字符串数组的元素查找,返回索引
    
    public class Homework02{
    	public static void main(String[] args) {
    		
    		A02 a02 = new A02();
    
    		String[] arr = {"you", "here", "are", "right"};
    		System.out.println("返回的索引:" + a02.find(arr, "are"));
    	}
    }
    
    class A02{
    
    	/*
    	思路:
    	方法名 find
    	形参 字符串数组
    	返回值 int
    
    	 */
    	public int find(String[] arr, String findThing){
    		int findPath = -1;
    		for(int i = 0; i < arr.length; i++){
    			if(arr[i].equals(findThing)){
    				findPath = i;
    				break;
    			}
    		}
    
    		return findPath;
    
    	}
    }
    
    • 作业3,定义一个类,包含书名和价格,可以实现自动对价格进行调整
    
    public class Homework03{
    	public static void main(String[] args) {
    		
    		Book bookPrice = new Book("岁月神偷", 200);
    		bookPrice.udpatePrice();
    		bookPrice.info();
    	}
    }
    
    class Book{
    	/*
    	
    	构造一个书类
    	实现改变数的价格
    	;类型,diuble
    	返回值 int
    
    	 */
    	String name;
    	double price;
    
    	// 构造器
    	public Book(String name, double price){
    		this.name = name;
    		this.price = price;
    	}
    	
    	public void udpatePrice(){
    		if(this.price > 150){
    			this.price = 150;
    		}
    		else if(this.price > 100){
    			this.price = 100;
    		}
    		
    	}
    
    	// 显示书籍情况
    	public void info(){
    		System.out.println("书名:" + this.name + " 价格 = " + this.price);
    	}
    }
    
    • 作业4: 编写一个类,实现数组的copy功能,输入旧数组,返回一个新数组
    
    public class Homework04{
    	public static void main(String[] args) {
    	// 方法返回值
    	int[] oldArr = {10, 30, 40};
    	A03 a3 = new A03();
    	int[] newArr = a3.copyArr(oldArr);
    
    	// 遍历
    	for(int i = 0; i < newArr.length; i++){
    		System.out.print(newArr[i] + "\t");
    	}
    
    	}
    }
    
    class A03{
    
    	/*
    	编写编写一个类,实现数组的copy功能,输入旧数组,返回一个新数组
    	实现一个方法,copyArr
    	返回一个新数组,元素和就数组一样
    	 */
    	public int[] copyArr(int[] oldArr){
    
    		int[] newArr = new int[oldArr.length];
    
    		for(int i=0; i < oldArr.length; i++){
    			newArr[i] = oldArr[i];
    		}
    
    		return newArr;
    	}
    
    }
    
    • 作业5 定义一个圆类,定义属性半径,提供显示圆周长的方法
    
    public class Homework05{
    	public static void main(String[] args) {
    		Cricle cl = new Cricle(2.5);
    		cl.circumference();
    		cl.area();
    
    	}
    }
    
    
    class Cricle{
    	double radius;
    
    	public Cricle(double radius){
    		this.radius = radius;
    	}
    
    	// 计算周长
    	public void circumference(){
    		double circleCum = 2*radius*Math.PI;
    		System.out.println("圆的周长为=" + circleCum);
    	}
    
    	// 计算面积
    	public void area(){
    		double circleArea = Math.PI * radius * radius;
    		System.out.println("圆的面积为=" + circleArea);
    	}
    
    }
    
    • 作业6 实现一个Cale计算类,输出两个变量表示两个操作数,定义加减乘除
    
    public class Homework06{
    	public static void main(String[] args) {
    		Cale cale = new Cale(5, 0);
    		System.out.println("和=" + cale.add());
    		System.out.println("减=" + cale.sub());
    		System.out.println("乘=" + cale.mul());
    		System.out.println("除=" + cale.div());
    
    	}
    }
    
    class Cale{
    
    	double a;
    	double b;
    
    	public Cale(double a, double b){
    		this.a = a;
    		this.b = b;
    	}
    
    	public double add(){
    		return a + b;
    	}
    
    	public double sub(){
    		return a - b;
    	}
    
    	public double mul(){
    		return a * b;
    	}
    
    	public Double div(){
    		if ( b == 0){
    			System.out.println("除数不能为0");
    			return null;
    		}
    		else{
    			return a / b;
    		}
    	}
    
    
    }
    
    • 作业7 设计一个Dog类,显示其信息
    
    public class Homework07{
    	public static void main(String[] args) {
    		Dog bai = new Dog("小白", "白色", 23);
    		bai.show();
    
    	}
    }
    
    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 show(){
    		System.out.println("名字:" + name + "颜色" + color + "年龄" + age);
    	}
    
    }
    
    • 作业8 答案是

    • 作业12 复用构造器

    
    public class Homework12{
    	public static void main(String[] args) {
    		Employee employee = new Employee("小金", "男", 12000);
    
    	}
    }
    
    class Employee{
    	// 先写少的
    	String name;
    	String gender;
    	int age;
    	String position;
    	double salary;
    
    	
    	public Employee(String name, String gender, int age){
    		this.name = name;
    		this.gender = gender;
    		this.age = age;
    	}
    
    	public Employee(String position, double salary){
    		this.position = position;
    		this.salary = salary;
    	}
    
    	public Employee(String name, String gender, int age, String position, double salary){
    		// this.name = name;
    		// this.gender = gender;
    		// this.age = age;
    		this(name, gender, age);
    		this.position = position;
    		this.salary = salary;
    	}
    
    }
    
    • 作业13 类进行调用
    
    public class Homework13{
    	public static void main(String[] args) {
    		Circle cl = new Circle();
    		PassObject ps = new PassObject();
    		ps.printAreas(cl, 5);
    	}
    }
    
    class Circle{
    	double radius;
    
    	public double findArea(){
    		return radius * radius * Math.PI;
    	}
    
    }
    
    class PassObject{
    
    	
    
    	public void printAreas(Circle cl, int times){
    		System.out.println("Radius"  + "\t\t" + "Area");
    
    		for(int i = 1;  i <=times; i++){
    			cl.radius = i;
    			System.out.println(cl.radius + "\t\t" + cl.findArea());
    		}
    	}
    
    	
    }
    
    • 作业14 电脑和Tom进行猜拳
    
    import java.util.Random;
    import java.util.Scanner;
    
    public class Homework14{
    	public static void main(String[] args) {
    		
    		Tom tom = new Tom();
    		tom.times = 3;
    		int sum = tom.Game();
    	}
    }
    
    class Tom{
    
    	/*
    	思路分析:
    	石头 0, 剪刀 1, 布 2
    
    	属性,出一个数
    	方法:可以跟电脑猜拳,并显示Tom输赢次数
    	 */
    	int guessTom;
    	int times;
    
    	public int Game(){
    
    		Scanner myScanner =  new Scanner(System.in);
    		int count =  0;
    		for(int i=0; i< times; i++){
    			int guessComputer = (int)(Math.random() * 3);
    			System.out.println("请输入Tom的值");
    			int guessTom = myScanner.nextInt();
    			if(guessTom == guessComputer){
    				System.out.println(i + "次平手");
    				continue;
    			}
    			else if (guessTom == 0 && guessComputer == 1 || guessTom == 1 && guessComputer ==2 || guessTom == 2 && guessComputer == 0){
    				count+=1;
    				System.out.println(i +"次\tTom赢了" + "电脑出的" + guessComputer + "Tom出的" + guessTom);
    			}
    			else{
    				System.out.println(i+ "Tom输了");
    			}
    
    		}
    
    		return count;
    		
    
    
    	}
    }
    
  • 相关阅读:
    Windows打开软件老是弹出无法验证发布者
    SpringMvc接受特殊符号参数被转义
    时代更替中的方正
    你应该知道的c# 反射详解
    C#使用System.Data.SQLite操作SQLite
    C# 动态调用WebService
    C# API: 生成和读取Excel文件
    11个强大的Visual Studio调试小技巧
    .Net 垃圾回收和大对象处理
    Visual Studio原生开发的10个调试技巧(一)
  • 原文地址:https://www.cnblogs.com/jly1/p/15700228.html
Copyright © 2011-2022 走看看