5.1 类与对象
☆思考题
张老太养了两只猫猫:一只叫小白,今年3岁,白色。还有一只叫小花,今年10岁,花色。
请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示 张老太没有这只猫猫。
☆分析
回顾上一章节的内容,学习了循环语句以及分支语句,考虑一下用这些语句,没用对象的概念来编写程序。
1、从题意可以,看出需要分支语句来判断是小白还是小花
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-5
功能:判断小白和小花两只猫
***********************************************************************
*/
import java.io.*;
public class Demo
{
public static void main(String []args)
{
System.out.println("********************");
System.out.println("* 欢迎来判断小猫猫 *");
System.out.println("* 输入‘退出’ *");
System.out.println("* 按下回车键 *");
System.out.println("* 就退出系统 *");
System.out.println("********************");
System.out.println();
//退出循环控制字符
int controll=1;
while(controll==1)
{
System.out.print("请输入猫的名字,然后按回车键: ");
try{
//从控制台接受用户输入的猫名字
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String caiName = br.readLine();
//判断输入的字符
if(caiName.equals("小白"))
{
System.out.println("喵喵,我是小白");
System.out.println("今年3岁");
System.out.println("白色");
}
else if(caiName.equals("小花"))
{
System.out.println("喵喵,我是小花");
System.out.println("今年10岁");
System.out.println("花色");
}
else if(caiName.equals("退出"))
{
controll=0;
}
else
{
System.out.println("张老太没有这只猫猫");
}
}catch(Exception e)
{
e.printStackTrace();
}
}//while
}
}
在编程的过程中,一定要注意一点:String类型的判断,如果用 == 来判断是不行的,需要用equals函数来判断才可以。或者采用其他手段,关于String类型,又是不少的知识点。
而且如果没有用对象的话,一种对象要描述的话需要三条语句重复打印,如果封装起来,那么就可以随时调用这个对象里面的属性,更加方便于控制使用。
☆对象
利用这个概念,可以将刚才一只猫的属性封装起来,调用起来就很方便,不用一条条代码地敲,先弄一下概念。
类的写法:
//java中如何做一个类(猫)【类名的首字母大写】
class Cat
{
//属性【成员变量】
int age;
String name;
String color;
……
}
对象的创建:
Cat xiaoBai = new Cat();
//设置属性
xiaoBai.age = 3;
xiaoBai.name = “小白”;
xiaoBai.color = “白色”;
设置完对象的属性之后,就可以开始随便地调用这个xiaoBai对象的属性了。
☆思考题
利用刚刚接触到【类】——》【对象】的概念,来简化刚才上面的代码。
1、写一个猫类
2、创建小白和小花两只猫的对象
3、在代码中进行调用
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-5
功能:判断小白和小花两只猫【运用类、对象】
***********************************************************************
*/
import java.io.*;
public class Demo
{
public static void main(String []args)
{
//创建小白的对象【实例】
Cat xiaoBai = new Cat();
xiaoBai.age = 3;
xiaoBai.name = "小白";
xiaoBai.color = "白色";
//创建小花的对象【实例】
Cat xiaoHua = new Cat();
xiaoHua.age = 10;
xiaoHua.name = "小花";
xiaoHua.color = "花色";
System.out.println("********************");
System.out.println("* 欢迎来判断小猫猫 *");
System.out.println("* 输入‘退出’ *");
System.out.println("* 按下回车键 *");
System.out.println("* 就退出系统 *");
System.out.println("********************");
System.out.println();
//退出循环控制字符
int controll=1;
while(controll==1)
{
System.out.print("请输入猫的名字,然后按回车键: ");
try{
//从控制台接受用户输入的猫名字
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String caiName = br.readLine();
//判断输入的字符
if(caiName.equals(xiaoBai.name))
{
System.out.println("喵喵,我是 "+xiaoBai.name);
System.out.println("今年"+xiaoBai.age+"岁");
System.out.println(xiaoBai.color);
}
else if(caiName.equals(xiaoHua.name))
{
System.out.println("喵喵,我是 "+xiaoHua.name);
System.out.println("今年"+xiaoHua.age+"岁");
System.out.println(xiaoHua.color);
}
else if(caiName.equals("退出"))
{
controll=0;
}
else
{
System.out.println("张老太没有这只猫猫");
}
}catch(Exception e)
{
e.printStackTrace();
}
}//while
}
}
//创建猫类
class Cat
{
int age;
String name;
String color;
}
可以很轻松地想到另一点,如果我们要改变小白的年龄,只需要在对象里面的属性进行修改就可以了。再也不用像之前一样一条条代码修改了。Oh yeach!
☆类和对象的区别和联系
通过上面的案例,可以看出:
1、类是抽象的,概念的,代表一类事物,比如人类,猫类……
2、对象是具体的,实际的,代表一个事物
3、类是对象的模板,对象是类的一个个体,实例(instance)
☆类——如何定义类
一个全面的类定义比较复杂,如下:
package 包名;
class 类名 extends 父类 implements 接口名
{
成员变量;
构造方法;
成员方法;
}
☆类——类的成员变量
成员变量是类的一个组成部分,一般是基本的数据类型,也可是 引用类型。例如,前面定义猫类的 int age 就是成员变量。
☆对象——如何创建对象
创建一个对象有两种方法
1、先声明再创建
对象声明:类型 对象名
对象创建:对象名 = new 类名()
2、一步到位
类型 对象名 = new 类名()
☆对象——如何创建对象
对象名.变量名;
5.1.1 成员变量
☆思考题
定义一个人类(Person)(包括 名字,年龄)。
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-6
功能:定义一个人类
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象【小明】
Person xiaoMing = new Person();
xiaoMing.age = 12;
xiaoMing.name = "小明";
System.out.println(xiaoMing.age);
System.out.println(xiaoMing.name);
}
}
//创建人类
class Person
{
int age;
String name;
}
☆思考题
对象之间是否可以直接通过 = 来赋值的呢?
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-6
功能:判断同一个类的对象是否可以直接通过 = 来赋值
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象【小明】
Person xiaoMing = new Person();
xiaoMing.age = 12;
xiaoMing.name = "小明";
//创建对象【小强】
Person xiaoQiang = new Person();
//将小明直接等于小强
xiaoQiang = xiaoMing;
//打印小强的姓名和年龄
System.out.println(xiaoQiang.age);
System.out.println(xiaoQiang.name);
}
}
//创建人类
class Person
{
int age;
String name;
}
可以从结果中看出,同一个类的对象是可以直接通过 = 号来直接赋值的。注意,通过 = 号的赋值并不是简单地直接传值而已,而是将内存空间,以及空间内部保存的变量一起传过去。如下图关系:
此时,因为xiaoMing和xiaoQiang两个对象都是指向同一个内存空间保存的变量。所以任意一个改变其中的变量,另一个对象提取当中变量的时候,也会改变。
☆练习
设置一个类,创建a、b、c三个对象,改变其中的变量,来查看变量的修改
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-9
功能:测试类的成员变量的赋值以及变化
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建3个对象
Person a = new Person();
//单独给a赋值,并创建内存空间
a.age = 10;
a.name = "史泰龙";
//直接将a的内存空间以及变量值 赋值 给 b
Person b;
b = a;
//将b指向a的内存空间以及变量值 赋值 给 c
Person c;
c = b;
//通过c来修改变量值,查看另外两个b与a的变量值是否改变,来验证三者是否都是指向同一个内存空间
c.age = 100;
c.name = "高圆圆";
System.out.println("c.age= "+c.age);
System.out.println("c.name= "+c.name);
System.out.println("b.age= "+b.age);
System.out.println("b.name= "+b.name);
System.out.println("a.age= "+a.age);
System.out.println("a.name= "+a.name);
}
}
//创建人类
class Person
{
int age;
String name;
}
通过结果可以得知,即使是以c=b=a的方式传值,三者依然是指向同一块内存空间,修改的变量值都保持一致。
5.1.2 成员方法
☆类-成员方法的初步介绍
在某些情况下,需要定义成员方法。例如人类:除了有一些属性外(成员变量表示的 年龄,姓名……),人类还有一些行为比如:可以说话、跑步、打人、吃饭……,通过学习,还可以做算术题。
这些情况下,就要用成员方法才能完成。
☆思考
1、添加speak成员方法,输出“我是一个好人”
2、添加jisuan成员方法,可以计算从 1+……+1000的结果
3、修改jisuan成员方法,该方法可以接受一个数n,计算从1+……+n的结果
4、添加add成员方法,可以计算两个数的和
☆类-类的成员方法(成员函数)定义
public 返回数据类型 方法名(参数列表)
{
语句;//方法(函数)主体
}
1、参数列表:表示成员函数输入
2、数据类型(返回类型):表示成员函数输出
3、函数主体:表示为了实现某一功能代码块
☆实现以上的方法
1、添加speak方法,输出“我很屌”
2、添加jisuan方法,计算1+……+1000
☆分析
Jisuan方法,可以写成等差数列的方法。
等差数列公式:
an = a1+(n-1)*d
Sn = (n*(a1+an))/2 = n*a1+(n*(n-1)*d)/2
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-9
功能:1、添加speak方法,输出“我很屌”
2、添加jisuan方法,计算1+……+1000
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
liuDeLi.speak();
liuDeLi.jisuan();
}
}
//创建人类
class Person
{
int age;
String name;
//speak方法
public void speak()
{
System.out.println("我很屌");
}//speak
//jisuan方法
public void jisuan()
{
double sum;
sum =(1000*(1+1000))/2;
System.out.println("1+……+1000= "+sum);
}//jisuan
}//Person
☆实现以上方法
1、修改jisuan成员方法,该方法可以接受一个数n,计算从1+……+n的结果
2、添加add成员方法,可以计算两个数的和
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-9
功能:1、添加speak方法,输出“我很屌”
2、修改jisuan成员方法,该方法可以接受一个数n,计算从1+……+n的结果
3、添加add成员方法,可以计算两个数的和
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
liuDeLi.speak();
liuDeLi.jisuan(1000);
liuDeLi.add(1,2);
}
}
//创建人类
class Person
{
int age;
String name;
//speak方法
public void speak()
{
System.out.println("我很屌");
}//speak
//jisuan方法
public void jisuan(int n)
{
double sum;
sum =(n*(1+n))/2;
System.out.println("1+……+1000= "+sum);
}//jisuan
//add方法
public void add(int a,int b)
{
int c;
c = a + b;
System.out.println("a+b= "+c);
}//add
}//Person
☆成员方法的重载
在成员方法中,如果两个方法的名字一样,则根据传输参数的不同来判定调用哪个方法
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-9
功能:方法的重载
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
liuDeLi.speak();
liuDeLi.speak("无敌槟榔哥");
}
}
//创建人类
class Person
{
int age;
String name;
//speak方法
public void speak()
{
System.out.println("我很屌");
}//speak
//speak方法的重载
public void speak(String name)
{
System.out.println("我的名字是 "+name+",我很屌");
}//speak
}//Person
可以从上面的代码中看出,Person类中有两个speak方法,通过传送 空值 或者 String 类型的值,则会分别调用不同的方法。这就是方法的重载(override)。
☆成员函数返回值
上面的成员函数中,都没有设置返回值。
现在将add方法修改为返回一个int值,看看该如何调用这个返回值!
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-10
功能:方法的返回值
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
System.out.println("1+10= "+liuDeLi.add(1,10));
}
}
//创建人类
class Person
{
int age;
String name;
//编写返回int值的add方法
public int add(int num1,int num2)
{
return num1+num2;
}//add
}//Person
注意:返回的类型和返回值的类型要一致
☆类的成员方法——声明
public int test(int a); //方法声明
这句话的作用是声明该方法,声明的格式为:
访问修饰符数据类型函数名(参数列表);
在给Person类添加add方法中,看到的关键字return,它的功能是把表达式的值返回给主调方法。
return 表达式;
注意:方法的声明没有函数体
☆类的成员方法(函数)——特别说明
方法的参数列表可以是多个(参数类型可以任意数据类型)
案例:在Person类中编写一个成员方法,从键盘输入三个数,返回最大的那个数。
☆代码
/*
***********************************************************************
作者:李俊挥
日期:2013-12-11
功能:方法的声明以及多个参数的方法
***********************************************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
System.out.println("最大值= "+liuDeLi.max(1,2,3));
}
}
//创建人类
class Person
{
int age;
String name;
//编写一个输入三个数,将最大值返回的方法
public int max(int a,int b,int c)
{
//定义一个中介值,用来传送最大值
int max;
//先判断a与b的大小,将大的值赋值给max
if(a>=b)
{
max = a;
}else
{
max = b;
}
//判断max与c的大小,将大的值赋值给max
if(max<c)
{
max = c;
}
return max;
}
}//Person
☆思考题
编写一个成员方法,从键盘输入一个整数(1-9),打印出对应的乘法表:
1*1=1
1*2=22*2=4
1*3=33*2=63*3=9
☆分析
1、需要用两个for循环,并且以循环嵌套的方式
2、可以从上面打印3行中找出规律
3、第一行 就相乘一次
4、第二行 需要相乘两次,整好为行数
5、第三行 需要相乘3次,也是行数
6、首先需要一个确定行数的循环
for(int i=1;i<=3;i++)
{
}
7、在进行每一行循环的过程中,还需要一个进行每行中打印所有列的循环
for(int i=1;i<=3;i++)
{
for(int j=1;j<=i;j++)
{
}// for j
}//for i
☆代码
/*
************************************
作者:李俊挥
日期:2013-12-14
功能:乘法列表
************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
liuDeLi.list();
}
}
//创建人类
class Person
{
int age;
String name;
//打印乘法列表
public void list()
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=i;j++)
{
System.out.print(j+"*"+i);
System.out.print(" ");
}//for j
System.out.println();
}//for i
}
}//Person
☆思考题
设计一个可以转置一个(3x3)二维数组的方法
123 1 47
4 56 2 58
789 3 69
☆分析
1、通过二维数组先记录第一个矩阵,如下:
A[0][0] = 1 , A[0][1] = 2 , A[0][2] = 3
A[1][0] = 4 , A[1][1] = 5 , A[1][2] = 6
A[2][0] = 7 , A[2][1] = 8 , A[2][2] = 9
转置后的数据,如下:
A[0][0] = 1 , A[0][1] = 4 , A[0][2] = 7
A[1][0] = 2 , A[1][1] = 5 , A[1][2] = 8
A[2][0] = 3 , A[2][1] = 6 , A[2][2] = 9
根据对应的颜色进行互换即可。
可以从中发现规律,只要把X,Y的坐标互换,即可。
2、写一个循环,逐个将x!= y 进行 xy 互换即可,例如:
int t;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
//明显这个 i<j 的判断很重要,不要会换来换去
if(i!=j&&i<j)
{
t=a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}//if
}//for j
}//for i
☆代码
/*
************************************
作者:李俊挥
日期:2013-12-17
功能:二维数组转置
************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person liuDeLi = new Person();
//调用成员方法
liuDeLi.zhuanzhi();
}
}
//创建人类
class Person
{
int age;
String name;
//打印乘法列表
public void zhuanzhi()
{
int t;
int [][]a = new int[3][3];
//第一个矩阵
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6;
a[2][0] = 7; a[2][1] = 8; a[2][2] = 9;
//转置
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i!=j&&i<j)
{
t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}//if
}//for j
}//for i
//打印矩阵
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
System.out.print(a[i][j]+" ");
}//for j
System.out.println();
}//for i
}
}//Person
5.1.3 构造方法
☆类的构造方法
构造方法是类的一种特殊的方法,它的主要作用是完成对对象的初始化。它有几个特点:
1、方法名和类名相同
2、没有返回值
3、在创建一个类的新对象时,系统会自动地调用该类的构造方法完成对新对象的初始化
☆例子
编写人类Pserson类的构造方法,创建一个13岁,小明的对象。
☆代码
/*
************************************
作者:李俊挥
日期:2013-12-19
功能:写一个Person类的构造方法,没有用this
************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person xiaoMing = new Person(28,"小明");
System.out.println("我叫"+xiaoMing.name);
System.out.println("我的年龄"+xiaoMing.age);
}
}
//创建人类
class Person
{
int age;
String name;
//构造方法
public Person(int age,String name)
{
age = age;
name = name;
}
}//Person
可以从结果看出,这个对象的初始化失败了。为什么失败了呢?是不是因为这段构造方法中的代码呢?
age = age;
name = name;
为了求证结果,我在这段代码前面使用this,如下
this.age=age;
this.name=name;
☆代码
/*
************************************
作者:李俊挥
日期:2013-12-19
功能:写一个Person类的构造方法,使用this
************************************
*/
public class Demo
{
public static void main(String []args)
{
//创建对象
Person xiaoMing = new Person(28,"小明");
System.out.println("我叫"+xiaoMing.name);
System.out.println("我的年龄"+xiaoMing.age);
}
}
//创建人类
class Person
{
int age;
String name;
//构造方法
public Person(int age,String name)
{
this.age = age;
this.name = name;
}
}//Person
这次的结果就初始化成功了。因为有了this的区别说明,让机器知道,有this前缀的值是要初始化的值,而没有的值是传进来的值。
☆特别说明
一个类可以定义多个不同的构造方法,比如:Person类可以定义一个只初始化人名的方法,不需要年龄。
☆代码
/*
************************************
作者:李俊挥
日期:2013-12-19
功能:定义多个构造方法
************************************
*/
public class Demo
{
public static void main(String []args)
{
//使用第一个构造方法,创建对象
Person xiaoMing = new Person(28,"小明");
System.out.println("我叫"+xiaoMing.name);
System.out.println("我的年龄"+xiaoMing.age);
System.out.println();
//使用第二个构造方法,创建对象
Person xiaoQiang = new Person("小强");
System.out.println("我叫"+xiaoQiang.name);
}
}
//创建人类
class Person
{
int age;
String name;
//构造方法1
public Person(int age,String name)
{
this.age = age;
this.name = name;
}
//构造方法2
public Person(String name)
{
this.name = name;
}
}//Person
☆类的默认构造方法
如果一个类没有定义构造方法,系统会自动生成一个默认构造方法。例如:Person类
Person(){
};
当创建一个Person对象时,Person xiaoMing = new Person();
默认的构造方法就会被自动地调用。
☆类的构造方法小结
1、构造方法名和类名相同
2、构造方法没有返回值
3、主要作用是完成对新对象的初始化
4、在创建新对象时,系统自动地调用该类的构造方法
5、一个类可以有多个构造方法
6、每个类都有一个默认的构造方法