workspace_day09

Test day08

public class Test8 {
	
1.面向对象思想编程内容的三条主线分别是什么?
答: ①Java类及类的对象:属性、方法、构造器;代码块、内部类
    ②面向对象的三大特征:封装性、继承性、多态性
    ③其他关键字:this,import,static,super,final,abstract,interface,package
 
	面向对象的编程思想?(类、对象;面向对象的三大特征;...)
	
2.谈谈你对面向对象中类和对象的理解,并指出二者的关系?
答: 类是对一类事物的描述,是抽象的、概念上的定义
	对象是实际存在的一个个体,也称为实例(instance)
	关系:对象是有类派生出来的
	
	面向对象程序设计的重点:类的设计
	设计类,就是设计类的成员
	
比如我们和控制台进行交互,需要提供一个类,
	这个由API提供好的叫scanner类,这是类的概念,
	我们正真执行的时候需要创建scanner的对象,
	通过这个对象去操作它的的功能和方法,
	来完成我们和控制台的交互。
For example, when we interact with the console, 
	we need to provide a class.
	This one provided by API is called Scanner class, 
	which is the concept of class.
	When we are actually executing, 
	we need to create the Scanner object, 
	through which we can operate its functions and methods to 
	complete our interaction with the console.

3.面向对象思想的体现一:类和对象的创建和执行操作有哪三步?
答: 创建类、设计类的成员
        创建类的对象(类的实例化)
        通过“对象.属性”或“对象.方法”调用对象的结构


4.画出如下代码在执行时的内存分配情况:
	class Car {
	       String color = "red";
	       int num = 4;
	       void show() {
	    	   int a = 10;
		   System.out.println("color="+color
				   +",num="+num);
	       }
	}
	class CarTest {
		public static void main(String[] args) {
			Car c1 = new Car();   
			Car c2 = new Car(); 
			c1.color = "blue";  
			c1.show();   
			c2.show();
		}  
	}
答: (见图)
	
[析]:
	内存解析第一步:观察main方法(从程序的入口入手)
在栈空间声明变量叫c1,
在堆空间new了一个对象(new出来的结构在堆空间中),
这个对象就有一个地址值,把地址值赋给变量c1,
通过栈空间c1的地址值就能找到(指向)堆空间中对象的实体。
	
	内存解析第二步:找属性(非static的属性放在堆空间),
color和num都已经显示初始化了,
本质是把默认初始化值null改为red,0改为4,
至此关于Car c1 = new Car(); 的属性解析完成。
	
	同理,对下一行代码Car c2 = new Car(); 进行解析,
c1,c2地址值不同,color和num显示初始化情况与c1相同,
c1.color = "blue"; 通过c1调color属性,red改为blue ,
c1.show(); 调c1的show方法,看上半部分代码void show(){ ,
通过对象调方法,方法内定义变量a,局部变量a放栈空间,a=10,
谁调这个show方法,调这个方法的对象就是color这个属性的对象
这里是拿c1调的show,输出就是c1的color和num。
	抛开对象谈属性是没有意义的。
	
	通过c1调的show方法,调完以后show方法结束,
在show方法定义的局部变量就销毁了,即为
a=10就出栈,其生命周期结束(栈:后进先出)。
	
	通过c2调show,又在栈内重新加载变量a=10,
输出c2的color和num,c2调的show方法结束后,
同时a=10就出栈,其生命周期结束。
	
	main方法全部结束后,c2、c1相继出栈,此时栈空间清空,
同时两个指针也就没有了,堆空间进行垃圾回收。
		
	

5.类的方法内是否可以定义变量?是否可以调用属性?
    是否可以定义方法?是否可以调用方法?
答: 是;
	是;
	否(方法是一个个独立的功能,彼此不相关);
	是。

}

 


Review day08 

 

虚拟机栈,即为平时提到的栈结构。我们将局部变量存储在栈结构中

堆,我们将new出来的结构(比如:数组、对象)加载在对空间中。补充:对象的属性(非static的)加载在堆空间中。 

方法区:类的加载信息、常量池、静态域

 


 

workspace day09 

自定义数组的工具类

/*
 * 搭配ArrayUtil.java(自定义数组工具)
 */

public class ArrayUtilTest {
	public static void main(String[] args) {
		
		ArrayUtil util = new ArrayUtil();
		int[] arr = new int[]{32,34,32,5,3,53,65,-99,0,-14};
		int max = util.getMax(arr);
		System.out.println("最大值为:" + max);
		
		
		System.out.println("排序前:");
		util.print(arr);
		
		
		util.sort(arr);
		System.out.println("排序后:");
		util.print(arr);
		
		System.out.println("查找:");
		int index = util.getIdex(arr, -5);
		if (index >= 0) {
			System.out.println("找到了,索引地址为:" + index);
		} else {
			System.out.println("未找到");
		}	
		
	}
}
/*
 * 自定义数组的工具类
 */
import java.util.Arrays;

public class ArrayUtil {
	
	//求数组最大值
	public int getMax(int[] arr) {
		int maxValue = arr[0];
		for (int i = 0; i < arr.length; i++) {
			if (maxValue < arr[i]) {
				maxValue = arr[i];
			}
		}
		return maxValue;
	}
	
	//求数组最小值
	public int getMin(int[] arr) {
		int minValue = arr[0]; 
		for (int i = 0; i < arr.length; i++) {
			if (minValue > arr[i]) {
				minValue = arr[i];
			}
		}
		return minValue;
	}
	
	//求数组的总和
	public int getSum(int[] arr) {
		int sum = 0;
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i];
		}
		return sum ;
	}
	
	//求平均值
	public int getAyg(int[] arr) {

		return getSum(arr) / arr.length;  //方法中调方法
	}	
	
	//反转数组
	public void reverse(int[] arr) {
		for (int i = 0; i < arr.length / 2; i++) {
			int temp = arr[i];
			arr[i] = arr[arr.length - i - 1];
			arr[arr.length - i -1] = temp;
		}
	}
	
	//复制数组
	public int[] copy(int[] arr) {
		int[] arr1 = new int [arr.length];
		for (int i = 0; i < arr1.length; i++) {
			arr1[i] = arr[i];
		}
		return arr1;
	}
	
	//数组排序
	public void sort(int[] arr) {
		// 冒泡排序
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - 1 - i; j++) {
				if (arr[j] > arr[j + 1]) { // ">":小到大
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
	}
	
	//遍历数组
	public void print(int[] arr) {
		for (int i = 0; i < arr.length; i++) {	
		}
		System.out.println(Arrays.toString(arr));
	}
	
	//查找指定元素
	public int getIdex(int[] arr, int dest) {
		//线性查找:
		for (int i = 0; i < arr.length; i++) {
			if (dest == arr[i]) {
				return i;
			}
		}
		return -1; //返回一个负数,表示没有找到
	}
	
}

 

/*
 * 一、理解“万事万物皆对象”
 * 1.在Java语言范畴中,我们都将功能、结构等封装到类中,
 * 	  通过类到实例化,来调用具体的功能结构。
 * 		>Scanner,String等
 * 		>文件:File
 * 		>网络资源:URL
 * 2.涉及到Java语言与前端 Html、后端的数据库交互时,
 *   前后端的结构在Java层面交互时,都体现为类、对象。
 * 
 * 二、内存解析的说明
 * 1.引用类型的变量,只可能存储两类值:
 * 	 null 或 地址值(含变量的类型)
 * 
 * 三、匿名对象的使用
 * 1.理解:我们创建的对象,没有显示的赋给一个变量名,
 * 		     即为匿名对象。
 * 2.特征:匿名对象只能调用一次。
 * 3.使用:如下
 */

public class InstanceTest {
 public static void main(String[] args) {
  Phone p = new Phone();
  System.out.println(p);
		
  p.sendEmail();
  p.playGame();
		
   //匿名对象
// new Phone().sendEmail();
// new Phone().playGame();
		
  new Phone().price = 9999;
  new Phone().showPrice(); //0.0  匿名对象只能调用一次
		
 //**********************************
  PhoneMall mall = new PhoneMall();

  //匿名对象的使用
  mall.show(new Phone());
		
 }
}

class PhoneMall{
 public void show(Phone phone) {
  phone.sendEmail();
  phone.playGame();
 }
}

class Phone{
 double price; //价格
	
 public void sendEmail() {
  System.out.println("发送邮件");
 }
	
 public void playGame() {
  System.out.println("玩游戏");
 }
	
 public void showPrice() {
  System.out.println("手机价格为:" + price);
 }
}

4.6.1 方法的重载

4.6.2 可变形参的方法

4.6.3 方法参数的值传递机制

4.6.4 递归方法

/*
一、方法的重载(overload)
1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
 	"两同一不同":
 	  ①同一个类、相同方法名
      ②参数列表不同:参数个数不同、参数类型不同
  
2.举例:Arrays中的sort(), binarySearch()。。。
  	
3.判断是否是重载:
  	  跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系。
  	 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。
  	 调用时,根据方法参数列表的不同来区别。
  
4.在通过对象调用方法时,如何确定某一个指定的方法:
  	  先看 方法名,再看 参数列表
  
5.重载举例
 //返回两个整数的和
 int add(int x.int y){return x+y;}
 //返回三个整数的和
 int add(int x,int y, int z){return x+y+z;}
 //返回两个小数的和
 double add(double x,double y){return x+y;}

 */
public class OverLoadTest {
 public static void main(String[] args) {
  OverLoadTest test = new OverLoadTest();
  test.getSum(1, 2);
 }
	
 //如下4个方法构成了重载
 public void getSum(int i, int j) {
  System.out.println("1");
 }
 //第一个方法注释掉之后不报错,会自动类型提升,选取其他结构
	
 public void getSum(double d1, double d2) {
  System.out.println("2");
 }
	
 public void getSum(String s, int i) {
  System.out.println("3");
 }
	
 public void getSum(int i, String s) { //参数顺序不同
  System.out.println("4");
 }
	
   //以下不构成重载
// public int getSum(int i, int j) {
// 	return 0;
// }

// public void getSum(int m, int n) {
// 	
// }
	
// private void getSum(int i, int j) {
// 	
// }
}

 

copyof 彼此之间成为重载:

 

/*
1.编写程序,定义三个重载方法并调用,方法名为mOL。
三个方法分别接收一个int参数,两个int参数,一个字符串参数。
分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。
在主类的main()方法中分别用参数区别调用三个方法。

2.定义三个重载方法max(),
第一个方法求两个int值中的最大值,
第二个方法求两个double值中的最大值,
第三个方法求三个double值中的最大值,
并分别调用三个方法。
*/
public class OverLoadExer {
 public static void main(String[] args) {
  OverLoadExer test = new OverLoadExer(); //这个程序,main函数写进了类OverloadExer里面
  //1.调用
  test.mOL(1);
  test.mOL(2, 4); //调用的是public void mOL(int i,int j)
  test.mOL("Outputstring"); //字符串要加" "

  
  //2.调用
  System.out.println(test.max(10, 13));
  System.out.println(test.max(1.1, -8.9));
  System.out.println(test.max(7, -9.1, -2.2));
 }

 //1.如下三个方法构成重载
 public void mOL(int i) {
  System.out.println(i * i);
 }
	
 public void mOL(int i, int j) {
  System.out.println(i * j);
 }
	
 public void mOL(String s) {
  System.out.println(s);
 }
	
	
 //2.如下三个方法构成重载
 public int max(int i, int j) {
  return (i > j) ? i : j; //三元
 }
	
 public double max(double d1, double d2) {
  return (d1 > d2) ? d1 : d2;
 }
	
 public double max(double d1, double d2, double d3) {
  double max = (d1 > d2) ? d1 : d2;
  return (max > d3) ? max : d3;
 }
}

 

4.6.2 可变形参的方法

/*
二、可变形参的方法
1. JDK 5.0新增的内容,允许直接定义能和多个实参相匹配的形参。
      从而,可以用一种更简单的方式,来传递个数可变的实参。

2. 具体使用:
①可变个数形参的格式:(数据类型 ... 变量名)

②当调用可变个数形参的方法时,
  传入的参数个数可以是:0个,1个,2个,…
  
③可变个数形参的方法与本类中方法名相同,
  形参不同的方法之间构成的重载。
  
④可变个数形参的方法与本类中方法名相同,
  形参类型也相同的数组之间不构成重载,他们二者不能共存。
 (String[] books) ⇔  (String ... books)
  
⑤可变个数形参在方法的形参中,必须声明在末尾。

⑥可变个数形参在方法中的形参中,最多只能声明一个可变形参。
*/
public class MethodArgsTest {
 public static void main(String[] args) {
  MethodArgsTest test = new MethodArgsTest();
  test.show(12);  //1
  test.show("hello");  //2     匹配1个
  test.show("hello", "world");  //3    匹配2个
  test.show();  //3     匹配没有的

  test.show("AA", "BB", "CC");
 }

 public void show(int i) {  //对应1
	 
 }

 //注释之后不报错,采用下面的
 public void show(String s) {  //对应2
  System.out.println("show(String)");
 }

 public void show(String ... strs) {  //对应3:可变个数形参
  System.out.println("show(String ... strs)");

  for (int i = 0; i < strs.length; i++) {
  System.out.println(strs[i]);
  }
 }

   //与上面的无法构成重载
   //可变个数形参的方法与本类中方法名相同,
   //形参类型也相同的数组之间不构成重载,他们二者不能共存。
// public void show(String[] strs) {
// 
// }

   //错误信息:The variable argument type String of the method show must be the last parameter
// public void show(String ... strs, int i) {
//  
// }  //必须声明在末尾--->(int i, String ... strs)
}

重点:

4.6.3 方法参数的值传递机制

/*
关于变量的赋值:
如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的地址值。
 */
public class ValueTransferTest {
 public static void main(String[] args) {
  System.out.println("**********基本数据类型**********");
  int m = 10;
  int n = m;
  System.out.println("m = " + m + ", n = " + n);
  
  n = 20;
  System.out.println("m = " + m + ", n = " + n);

  System.out.println("**********引用数据类型**********");
  Order o1 = new Order();
  o1.orderId = 1001;
  Order o2 = o1;  //赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体。
  System.out.println("o1.orderId = " + o1.orderId 
		  		 + ", o2.orderId = " + o2.orderId);
  
  o2.orderId = 1002;
  System.out.println("o1.orderId = " + o1.orderId 
		  		 + ", o2.orderId = " + o2.orderId);
 }
}

class Order {
 int orderId;
}

 

/* 三、方法形参的传递机制:值传递

1.形参:方法定义时,声明的小括号内的参数。
    实参:方法调用时,实际传递给形参的值。
 
2.值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
 */
public class ValueTransferTest1 {
 public static void main(String[] args) {
  int m = 10;
  int n = 20;
  System.out.println("m = " + m + ", n = " + n);
    //交换两个变量的值的操作
//  int temp = m;
//  m = n;
//  n = temp;

ValueTransferTest1 test = new ValueTransferTest1();
  test.swap(m, n);
  System.out.println("m = " + m + ", n = " + n);
 }
 public void swap(int m, int n) {
  int temp = m;
  m = n;
  n = temp;
 }
}

 

易错面试题 

1.

//附加题:(每题10分) 1.
public class Test { 
 public static void main(String[]args) {
  int a=10; 
  int b=10; 
  method(a,b);/*需要在method方法被调用之后,
                仅打印出a=100,b=200,
                请写出method方法的代码 */
  System.out.println("a="+a);
  System.out.println("b="+b);
 }
//代码编写处
}


	
//法一:
public static void method(int a, int b) {
// 在不改变原本题目的前提下,如何写这个函数才能在main函数中输出a=100,b=200?
a = a * 10;
b = b * 20;
System.out.println(a);
System.out.printin(b);
System.exit(O);  //退出程序
}
	
	
//法二:
public static void method(int a, int b){
	
PrintStream ps = new PrintStream(System.out){
@Override 
public void printin(String x){

if("a=10".equals(x)){
x="a=100";
}else if("b=10".equals(x)){
x="b=200";
}
super.println(x);
}
};

System.setOut(ps);

}

 2.

3.如下代码输出结果是什么?

  	int[] arr1 = new int[]{1,2,3};
    System.out.println(arr1);
    char[] arr2 = new char[]{'a','b','c'};
    System.out.println(arr2);

 输出:

[I@blbc7ed
abc

[析]:

或许认为简单,心想输出的结果都是地址值,其实,正确的结果是:第一个是地址值,第二个是abc。

调用的System.out.println(arr1); 方法实际上是PrintStream里的println(Object)方法,而System.out.println(arr2); 实际上调用的是PrintStream里的println(char[])方法。println(char[])方法中对char[]进行了遍历.

 

练习6:将对象作为参数传递给方法
(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积。
(2)定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:                public void printAreas(Circle c,int time)
在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。
(3)在main方法中调用printAreas()方法,调用完毕后输出当前半径值,程序运行结束如图所示。

/*
(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,
一个findArea()方法返回圆的面积。
*/

public class Circle {
 double radius; //半径
 
 //求圆面积
 public double findArea() {
  return Math.PI * radius * radius;
 }
}
/*
 考察参数的值传递
 
(2)定义一个类PassObject,在类中定义一个方法printAreas(),
该方法的定义如下:public void printAreas(Circle c, int time)
在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。
例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积。

(3)在main方法中调用printAreas()方法,调用完毕后输出当前半径值,
程序运行结束如图所示。
 */
public class PassObject {

 public static void main(String[] args) {
  PassObject test = new PassObject();
  Circle c  = new Circle();
  test.printAreas(c, 5);
  
  System.out.println(" now radius is:" + c.radius);
 }
	
 public void printAreas(Circle c, int time) {
  System.out.println("Radius\t\tArea");
  
  for (int i = 1; i <= time; i++) {
	//设置圆的半径 方法一
    c.radius = i;
    System.out.println(c.radius + "\t\t" + c.findArea());
    
    //方法二
//  c.radius = i;
//  double area = c.findArea();
//  System.out.println(c.radius + "\t\t" + area);
  }
  
  c.radius = time + 1; //为了能输出6.0 now radius is 6.0
 }
}
  另一种for循环写法:
  
  int i = 1;
  for (; i <= time; i++) {
    //设置圆的半径方法二
    c.radius = i;
    double area = c.findArea();
    System.out.println(c.radius + "\t\t" + area);
  }
  
  c.radius = i;

4.6.4 递归方法  阶乘n!

/* 四、递归方法的使用 (了解)

递归(recursion)方法:一个方法体内调用它本身

1.方法递归包含一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
2.递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
 */

public class RecursionTest {
 public static void main(String[] args) {
  //例1.计算1-100之间所有自然数的和
  //方式一:for循环
  int sum = 0;
  for (int i = 1; i <= 100; i++) {
   sum += i;
  }
  System.out.println("sum  = " + sum);

  //方式二:递归
  RecursionTest test = new RecursionTest();
  int sum1 = test.getSum(100);
  System.out.println("sum1 = " + sum1);

  System.out.println("*******************");
  
  int value = test.f(10);
  System.out.println("f(10) = " + value);
 }

 //计算1-n之间所有自然数的和
 public int getSum(int n) {
  if (n == 1) {
   return 1;
  } else {
   return n + getSum(n - 1);
  }
 }

 //例2.计算1-n之间所有自然数的乘积:n!
 public int getSum1(int n) {
  if (n == 1) {
   return 1;
  } else {
   return n * getSum1(n - 1);
  }
 }

 //例3.已知数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),
 //其中n是大于0的整数,求f(10)的值。
 public int f(int n) {
  if (n == 0) {
   return 1;
  } else if (n == 1) {
   return 4;
  } else {
   return 2 * f(n - 1) + f(n - 2);
  }
 }
 
 //例4.斐波那契数列
 //输入一个数据n,计算斐波那契数列的第n个值,
 //1 1 2 3 5 8 13 21 34 55,
 //规律:一个数等于前两个数之和,
 //要求:计算斐波那契数列(Fibonacci)的第n个值,
 //并将整个数列打印出来.
 
 //例子5.汉诺塔问题
 
 //例子6.快排
}

输出:

sum  = 5050
sum1 = 5050
*******************
f(10) = 10497
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值