每日一考
面向对象思想编程内容的三条主线分别是什么
① 类及类的成员:属性、方法、构造器;代码块、内部类;
② 面向对象的三大特征:封装、继承、多态
③ 其他关键字:this、super、abstract、interface、static、final、package、import
面向对象的编程思想?
(类、对象;面向对象的三大特征;)谈谈你对面向对象中类和对象的理解,并指出二者关系
类:抽象的、概念上的内容
对象:实实在在存在的一个个体。
对象是由类派生出来的。面向对象思想的体现一:类和对象的创建和执行操作有哪三步?
①创建类
②new对象(类的实例化)
③调用类对象的结构:”对象.属性“ ”对象.方法“画出如下代码在执行时的内存分配情况 ```java 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();
} }
<br />
5.
类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?
<br />是;是;否;是
<a name="bfec0fd0"></a>
### 5.1对象数组的内存解析
<a name="560ca558"></a>
### 5.2 匿名对象
```java
package com.atguigu.java;
/*
* 一、理解”万事万物皆对象“
* 1.在jav语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
* >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.play();
//匿名对象
/*new Phone().sendEmail();
new Phone().play();*/
new Phone().price = 1999;
new Phone().showPrice();//0.0
//****************************
PhoneMall mall = new PhoneMall();
// mall.show(p);
//匿名对象的使用
mall.show(new Phone());//实参的值传递给形参
}
}
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.play();
}
}
class Phone{
double price;
public void sendEmail(){
System.out.println("发送邮件");
}
public void play(){
System.out.println("玩游戏");
}
public void showPrice(){
System.out.println("价格" + price);
}
}
自定义工具类
package com.atguigu.java;
/*
* 自定义工具类
*/
public class ArrayUtil {
//求数组的最大值
public int getMax(int[] arr){
int maxValue = arr[0];
for(int i = 1;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 = 1;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 getAvg(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 - 1 -i];
arr[arr.length - 1 -i] = 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.print(arr[i] + "\t");
}
}
//查找指定元素
public int getIndex(int[] arr,int dest){
for(int i = 0;i < arr.length;i++){
if(dest == arr[i]){
return i;
}
}
return -1;//返回负数,表示没找到
}
}
package com.atguigu.java;
public class ArrayUtilTest {
public static void main(String[] args){
ArrayUtil util = new ArrayUtil();
int[] arr = new int[]{32,34,32,5,65,-98,100};
int max = util.getMax(arr);
System.out.println(max);
util.sort(arr);
util.print(arr);
System.out.println("查找:");
int index = util.getIndex(arr, 5);
if(index >= 0){
System.out.println("找到了,索引地址为:" + index);
}else{
System.out.println("未找到");
}
}
}
六、再谈方法
6.1 方法的重载
6.1.1 重载的概念:
在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
“两同一不同”:
同一个类、相同方法名
参数列表不同:参数个数不同,参数类型不同
package com.atguigu.java1;
/* 方法重载(overload)loading
* 1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
* "两同一不同":同一个类、相同方法名
* 参数列表不同:参数个数不同,参数类型不同
* 2.举例.
* Arrays类中重载的sort() / binarySearch()
*
* 3.判断是否重载
* 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系
*
* 4.在通过对象调用方法时,如何确定某个指定的方法
* 方法名 ---> 参数列表
*/
public class OverLoadTest {
public static void main(String[] args) {
OverLoadTest test = new OverLoadTest();
//如果把1方法注释,依然不会报错,有自动类型提升int型赋给double型
test.getSum(1, 2);
}
//如下的4个方法构成重载
//1.
/*public void getSum(int i,int j){
System.out.println("1");
}*/
//2.
public void getSum(double i,double j){
System.out.println("2");
}
//3.
public void getSum(String s,int i){
System.out.println("3");
}
//4.
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){//不算重载
}*/
}
6.1.2 重载的特点:
与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
6.1.3 重载示例:
//返回两个整数的和
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;}
例如:
例如,System.out.println()方法就是典型的重载方法,其内部的声
明形式如下:
public void println(byte x)
public void println(short x)
public void println(int x)
public void println(long x)
public void println(float x)
public void println(double x)
public void println(char x)
public void println(double x)
public void println()
6.1.4 练习
- 判 断:
1.判 断:
与void show(int a,char b,double c){}构成重载的有:
a) void show(int x,char y,double z){} // no
b) int show(int a,double c,char b){} // yes
c) void show(int a,double c,char b){} // yes
d) boolean show(int c,char b){} // yes
e) void show(double c){} // yes
f) double show(int x,char y,double z){} // no
g) void shows(){double c} // no
.编写程序,定义三个重载方法并调用。方法名为mOL。
三个方法分别接收一个int参数、两个int参数、一个字符串参数。分别 执行平方运算并输出结果,相乘并输出结果,输出字符串信息。
在主类的main ()方法中分别用参数区别调用三个方法。
定义三个重载方法max(),第一个方法求两个int值中的最大值,第二个方
法求两个double值中的最大值,第三个方法求三个double值中的最大值,
并分别调用三个方法。 ```java package com.atguigu.exer;
/*
- 2.编写程序,定义三个重载方法并调用。方法名为mOL。
- 三个方法分别接收一个int参数、两个int参数、一个字符串参数。
- 分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。
- 在主类的main ()方法中分别用参数区别调用三个方法。
- 3.定义三个重载方法max(),第一个方法求两个int值中的最大值,
- 第二个方法求两个double值中的最大值,
- 第三个方法求三个double值中的最大值,
- 并分别调用三个方法 */
public class OverloadExer {
//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;
}
}
<a name="e36aea25"></a>
### 6.2 可变个数的形参
JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。
**说明:**
1. 声明格式:方法名(参数的类型名 ...参数名)
2. 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
3. 可变个数形参的方法与同名的方法之间,彼此构成重载
4. 可变参数方法的使用与方法参数部分使用数组是一致的
5. 方法的参数部分有可变形参,需要放在形参声明的最后
6. 在一个方法的形参位置,最多只能声明一个可变个数形参
```java
package com.atguigu.java1;
/*
* 可变个数形参的方法
*
* 1.jdk 5.0新增的内容
* 2.具体使用
* 2.1 可变个数形参的格式,数据类型...变量名
* 2.2 当调用可变个数形参的方法时,传入的参数个数可以是,0个,1个,2个,多个
* 2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
* 2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载
* 换句话说:二者不能共存
* 2.5 可变个数形参在方法的形参中,必须声明在末尾(见方法5)
* 2.6 可变个数形参在方法的形参中,最多只能声明一个可变形参
*/
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
test.show("hello");//优先考虑方法2
test.show("hello","world");//方法3
test.show();//3.
test.show("AA","BB","CC");
//test.show(new String[]{"AA","BB","CC"});
}
//1.
public void show(int i){
}
//2.非常确定,优先考虑
/*public void show(String s){
System.out.println("show(String)");
}*/
//3.
public void show(String ... strs){//可变个数(和数组一样)
System.out.println("show(String...strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}
//4.和方法3不能共存(编译器认为二者没区别)
/*public void show(String[] strs){
}*/
//5.报错(必须把可变个数形参声明在末尾,就像方法6一样)不能把可变的个数放在前面
//The variable argument type String of the method
//show must be the last parameter
/*public void show(String ...strs,int i){
}*/
//6.
public void show(int i,String ...strs){
}
}
6.3 方法参数的值传递机制[重点、难点]
方法,必须由其所在类或对象调用才有意义。若方法含有参数:
- 形参:方法声明时的参数
- 实参:方法调用时实际传给形参的参数值
Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。- 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
- 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参
package com.atguigu.java1;
/*
* 关于变量的赋值
*
* 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
* 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
*/
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;
}
值传递:
package com.atguigu.java1;
/*
* 方法的形参的传递机制:值传递
*
* 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;
}
}
引用传递:
package com.atguigu.java1;
/*
* 方法的形参的传递机制:值传递
*
* 1.形参:方法定义时,声明的小括号内的参数
* 实参:方法调用时,实际传递给形参的数据
*
* 2.值传递机制:
* 如果参数是基本数据类型,此时实参赋给形参的是,实参真实存储的数据值。(形参在栈中)
* 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
*
*/
public class ValueTransferTest2 {
public static void main(String[] args) {
Data data = new Data();
data.m = 10;
data.n = 20;
System.out.println("m = " + data.m + ", n = " + data.n);
/*//交换m和n的值
int temp = data.m;
data.m = data.n;
data.n = temp;*/
//对象
ValueTransferTest2 V1 = new ValueTransferTest2();
V1.swap(data);
System.out.println("m = " + data.m + ", n = " + data.n);
}
public void swap(Data data){//传递过来的是地址值,指向之前开辟的空间
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
class Data{
int m;
int n;
}
例题:
public class TransferTest3 {
public static void main(String args[]) {
TransferTest3 test = new TransferTest3();
test.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}
public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + " " + i);
} }
class Value {
int i = 15;
}