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;
    		
    
    
    	}
    }
    
  • 相关阅读:
    POJ 1003 解题报告
    POJ 1004 解题报告
    POJ-1002 解题报告
    vi--文本编辑常用快捷键之光标移动
    常用图表工具
    September 05th 2017 Week 36th Tuesday
    September 04th 2017 Week 36th Monday
    September 03rd 2017 Week 36th Sunday
    September 02nd 2017 Week 35th Saturday
    September 01st 2017 Week 35th Friday
  • 原文地址:https://www.cnblogs.com/jly1/p/15700228.html
Copyright © 2011-2022 走看看