1、2019/5/16,1,第6章,类与对象,2019/5/16,2,通过本章的学习,主要掌握以下知识点:类的基本概念 对象的创建与使用 对象的使用 成员的调用 本章的重点:创建类 本章的难点:类修饰符成员数量与成员方法修饰符,2019/5/16,3,在前面的章节中,对Java的简单数据类型、数组、运算符和表达式及流程控制的方法作了详细的介绍。从本章开始将介绍面向对象的程序设计方法。面向对象的编程思想是力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能的一致。所以在面向对象的程序设计中, 类(Class)和对象(Object)是面向对象程序设计方法中最核心概念。,2019/5/16
2、,4,包括技术:封装 、继承、多态 核心概念:类对象特点: 数据存储(变量)、数据处理(函数),面向对象编程技术,是创建对象的模板,是具有相同属性和相同行为的对象的模板。,是类的具体实例(实体),任何具体对象必然隶属于一个类。,封装在对象中,面向对象编程技术,2019/5/16,5,例:变量 name鱼名称 color鱼颜色 函数setValue() 赋值 name、coloroutput() 显示 name、color分别用“面向过程”、“面向对象” 编程思想实现。,面向对象编程技术,2019/5/16,6,# include char name20=“ ”; char color20=“
3、”; main() void setValue(char n, char c); void output(); setValue(“Shark”,”white”); output(); setValue(“Golden”,”orange”); output(); void setValue(char n,char c ) strcpy(name,n); strcpy(color,c); /error: name=n; color=c; void output() printf(“%s”,name); printf(“s”,color); ,面向对象编程技术,1. 面向过程源程序: Fish.c
4、,特点:数据与操作 分离,数据2,操作,数据1,变量,函数,数据n,2019/5/16,7,public class Fish /关键字class定义类 String name ; /属性变量name描述鱼的名字String color; /属性变量color描述鱼的颜色void setValue (String n, String c ) /方法setValue :给成员变量赋值 name=n;color=c;void output( ) /方法output :显示成员变量 System.out.println (name);System.out.println (color); publi
5、c static void main(String args) Fish f1 = new Fish (); /创建Fish类的对象f1.setValue(“Shark”,”red”); f1.output( ); Fish f2 = new Fish (); /创建Fish类的对象f2.setValue(“Golden”,” orange”); f2.output( ); ,2. 面向对象源程序: Fish.java,面向对象编程技术,说明:不需要函数声明,特点:数据与操作 整合,2019/5/16,8,6.1 类的基本概念,类的概念是为了让程序设计语言能更清楚地描述日常生活中的事物。类是对
6、某一类事物的描述,是抽象的、概念上的定义;而对象则是实际存在的属该类事物的具体的个体,称为实例(Instance)。下面用一个现实生活中的例子来说明类与对象的概念。图6.1所示的是一个“汽车类”与“汽车实例”的例子。,2019/5/16,9,2019/5/16,10,其中,汽车设计图就是“汽车类”,由这个图纸设计出来的若干个汽车就是按照该类生产出的“汽车对象”。,2019/5/16,11,一般来说,类是由数据成员与函数成员封装而成的,其中数据成员表示类的属性,函数成员表示类的行为。 例:下面用Java类来描述圆柱体,并能保存圆柱体的信息(底半径和高),而且还能利用此类计算出圆柱体的面积和体积。
7、 PPT-P10 P18代码,2019/5/16,12,每一个圆柱体,无论尺寸大小,都有底半径和高这两个属性,而这两个属性就是圆柱体的数据,因此就本例而言,radius(半径)与height(高)可以说是圆柱体类的数据成员(data member)。 除了底半径和高这两个数据之外,还可以把计算底面积与体积这两个函数纳入圆柱体类里,变成类的函数成员(function member)。Java称这种封装于类内的函数为“方法”(method)。,2019/5/16,13,所谓的“类”就是把事物的数据与相关功能封装(Encapsulate)在一起,形成一种特殊的数据结构,用以表达真实事物的一种抽象。“
8、Encapsulate”原意是“将装入胶囊内”,现在胶囊就是类,而成员变量与成员方法便是被封入的东西。图6.2为圆柱体类的示意图。 由图6.2可知,圆柱体类的成员变量有pi、radius与height,而成员方法则有计算面积的area()与计算体积的volume ()。,2019/5/16,14,2019/5/16,15,6.2 定义类,1类的一般结构类修饰符 class 类名称 声明成员变量修饰符 数据类型 成员变量名称;修饰符 返回值的数据类型 方法名(参数1,参数2,)语句序列;return 表达式; ,2019/5/16,16,定义类 (声明类)类名组成字母 下划线_ $ 数字约定每个
9、单词的首字母大写。例:,类的创建,修饰 class 类名 成员变量(属性变量) 定义成员函数(成员方法 ) 定义 ,开头,Fish ExceptionArray,类的创建,2019/5/16,17,成员变量(属性变量)概念例e: 找错,在类体之中、方法体之外定义的变量。(注意:必须在类体之中),int height=260; Class Book / class 小写 int width=185;public void setWidth(int x)int y ; ,类的创建,没有: 全局变量,说明: Java 中: 定义成员变量初值; 对!C+中: 定义成员变量初值; 错!,2019/5/1
10、6,18,(1)从语法形式上看,成员变量是属于类的,而局部变量是在方法中定义的变量或方法的参数;成员变量可以被public、private、static等修饰符所修饰,而局部变量则不能被访问控制修饰符及static所修饰;成员变量和局部变量都可以被final所修饰。,4. 成员变量与局部变量的区别,2019/5/16,19,(2)从变量在内存中的存储方式上看,成员变量是对象的一部分,而对象是存在于 堆内存的,而局部变量是存在于栈内存的。(3)从变量在内存中的存在时间上看,成员变量是对象的一部分,它随着 对象的创建而存在,而局部变量随着 方法的调用而产生,随着方法调用的结束而自动消失。,2019
11、/5/16,20,(4)成员变量如果没有被赋初值, 则会自动以类型的默认值赋值(有一种情况例外,被final修饰但没有被static修饰的成员变量必须显式地赋值);而局部变量则不会自动赋值,必须显式地赋值后才能使用。,2019/5/16,21,成员方法(函数)作用 对本类的属性变量进行操作定义例r:例r:方法名,类的创建,修饰 返回类型 方法名 (参数部分) ,public int total (int e ,int m,int c) return e+n+c;,void setWidth (int w) width=w;,是:合法的Java标识符且不能是关键字 约定:首单词小写,后面各单词首
12、字母大写,2019/5/16,22,成员方法(函数) 参数部分 例r: 例e:,类的创建,( )必须有 形参变量可有、可无,void setWidthHeight (int w, int h) width=w; height=h; ( int w, h ) 错,void showWidthHeight ( ) System.out.println(“width=,height=”+width+height); void showWidthHeight / 错 System.out.println(“width=,height=”+width+height); ,2019/5/16,23,成员方
13、法(函数)返回类型,类的创建,含义告诉用户方法执行完,返回什么类型的值。说明返回类型部分必须有。基本类型 byte short char int long float double boolean 例r:引用类型类的类型例r:void不返回任何值例r:例e:,boolean m() return true;,Fish getFish() return new Fish(“Shark”,”Red”); ,void showWidthHeigth() System.out.println(“width=”+width);System.out.println(“height=”+height); ,
14、showWidthHeight(),2019/5/16,24,成员方法(函数)return 语句 作用格式1例r:返回类型void 方法体 return;例e:对错?,类的创建,结束方法体执行,返回调用该方法处。,void showWidthHeight() System.out.println(“width=,height=”+width+height);return; (等价:不写return;语句) ,public int total (int e, int m, int c) return; ,return;,2019/5/16,25,成员方法(函数)return 语句格式2例:匹配
15、函数返回类型,类的创建,public int total (int e, int m, int c) return e+m+c; 等价 return ( e+m+c); 对! / return 3.0; 错! ,2019/5/16,26,表6.1类修饰符的含义,2019/5/16,27,表6.2成员变量修饰符的含义,2019/5/16,28,表6.3成员方法修饰符的含义,2019/5/16,29,下面定义前面叙述过的圆柱体类如下: class Cylinder /定义圆柱体类Cylinder double radius; /声明成员变量radiusint height; /声明成员变量heig
16、htdouble pi=3.14; /为数据成员赋初值void area( ) /定义成员方法area(),用来计算底面积System.out.println(“圆柱底面积=”+ pi*radius* radius);void volume( ) /定义成员方法volume (),用来计算体积System.out.println(“圆柱体体积=”+(pi*radius* radius)*height); ,2019/5/16,30,6.3 对象的创建与使用,对象是整个面向对象程序设计的理论基础,由于面向对象程序中使用类来创建对象,所以可以将对象理解为一种新型的变量,它保存着一些比较有用的数据,
17、但可以要求它对自身进行操作。,2019/5/16,31,生成对象第1步第2步第3步,对象,定义 对象的引用变量 类名 变量名;,产生对象 new 类名 ();,对象首地址,返回:首地址,Student p;,p=new Student();,“堆”内存区,对象,引用变量 p,首地址赋值给引用变量,p=new Student();,2019/5/16,32,生成对象例r: 等价区分:,对象,对象、对象的引用,成员变量 连续的存储空间成员方法,变量存储对象首地址。,2019/5/16,33,表6.4 成员变量的默认初始值,2019/5/16,34,对象的内容包含不包含例:上例student类的执行
18、过程,对象,非static成员变量、非static成员方法,static成员变量、static成员方法,类运行前static 的变量teacher 在“static”区分配空间static 的方法main(),JAVA虚拟机在“static”区找到main()方法,开始执行,2019/5/16,35,使用对象含义格式例r:使用对象,对象,使用对象中的变量(赋值、显示) 调用对象中的方法,对象引用.成员变量 对象引用.成员方法,public static void main(String args) Student p=new Student();p.name=“张三”;System.out.p
19、rintln(“姓名”+p.name);p.setName(“张三”,20,75); ,2019/5/16,36,【例6.1】定义一个圆柱体类,并创建相应的对象,然后计算圆柱体的底面积与体积。,2个类,2019/5/16,37,/app6_1.java 圆柱体类Cylinder class Cylinder /定义Cylinder类 double radius; /定义成员变量radiusint height; /定义成员变量heightdouble pi=3.14;void area() /定义无返回值的方法area(),用来计算圆柱底面积System.out.println(“底面积=”+
20、pi* radius* radius);double volume () /定义返回值为double型的方法volume (),计算体积return (pi* radius* radius)*height; ,【例6.1】续,2019/5/16,38,public class app6_1 /目的:生成Cylinder 的对象 public static void main(String args ) /程序执行的起始点Cylinder volu; /定义对象的引用变量volu=new Cylinder(); /创建新的对象volu.radius=2.8; /赋值圆柱volu的底半径volu.
21、height=5; /赋值圆柱volu的高System.out.println(“底圆半径=”+volu.radius); /输出底圆半径System.out.println(“圆柱的高=”+volu.height); /输出圆柱的高System.out.print(“圆柱”);volu.area(); /输出面积System.out.println(“圆柱体体积=”+volu.volume(); /输出体积 ,【例6.1】续,2019/5/16,39,程序运行结果如下: 底圆半径=2.8 圆柱的高=5 圆柱底面积=24.6176 圆柱体体积=123.088,【例6.1】续,2019/5/16
22、,40,【例6.2】创建多个圆柱体类Clyinder的对象,修改其中一个对象的成员变量pi的值,其他对象中的pi值不受影响。,2019/5/16,41,/app6_2.java 圆柱体类Cylinder的成员在内存中的分配关系 class Cylinder /定义Cylinder类 double radius;int height;double pi=3.14;void area()System.out.println(“底面积=“+pi* radius* radius);double volume()return (pi* radius* radius)*height; ,2019/5/16
23、,42,public class app6_2 /定义公共类 public static void main(String args)Cylinder volu1,volu2; /声明指向对象的变量volu1和volu2volu1=new Cylinder(); /创建对象圆柱1:volu1volu2=new Cylinder(); /创建对象圆柱2:volu2volu1.radius= volu2.radius=2.5;volu2.pi=3; /修改volu2的pi值System.out.println(“圆柱1底半径=“+volu1.radius);System.out.println(“
24、圆柱2底半径=“+volu2.radius);System.out.println(“圆柱1的pi值=“+volu1.pi);System.out.println(“圆柱2的pi值=“+volu2.pi);System.out.print(“圆柱1“);volu1.area();System.out.print(“圆柱2“);volu2.area(); /运行结果?,2019/5/16,43,6.4 参数的传递,方法既可以有返回值,也可以没有参数,但在此之前我们所编写的程序中没有传递任何参数,如例6.3中的area()方法与volume()。,基本类型 引用类型,值传递,2019/5/16,4
25、4,参数传递,形参类型基本类型引用类型“值传” 实参值,参数传递,基本类型,引用类型,void m1 ( int x) ,void m2 (Cylinder x) ,m1(10);,传对象的首地址,2019/5/16,45,例3-10: 传值参数:基本类型例6.5 例6.6 :传值参数:引用类型,public class PassValue / 例3-10 static void exchange (int a, int b) int temp; temp=a; a=b; b=temp; public static void main(String args) int i=10; int j=
26、100; System.out.println(“i= j=”+i+”t”+j);exchange(i ,j);System.out.println(“i= j=”+i+”t”+j); / 结果?,参数传递,2019/5/16,46,6.4.2 以数组作为参数或返回值的方法调用,一、传递数组 要传递数组到方法里,只要指明传入的参数是一个数组即可。【例6.5】以一维数组为参数的方法调用,求若干数的最小值。,引用类型参数,2019/5/16,47,/app6_5.java 以数组为参数的方法调用 public class app6_5 /定义主类 public static void main(S
27、tring args)int a=8,3,7,88,9,23; /定义一维数组aLeastNumb MinNumber=new LeastNumb ();MinNumber.least(a); /将一维数组a传入least t()方法 ,【例6.5】续,2019/5/16,48,class LeastNumb /定义另一个类 public void least ( int array ) /参数array接收一维整型数组int temp=array0;for (int i=0;iarrayi)temp=arrayi;System.out.println(“最小的数为:”+temp); ,【例6
28、.5】续,程序运行结果为: 最小的数为:3,2019/5/16,49,二、返回值为数组类型的方法 一个方法如果没有返回值,则在该方法的前面用void来修饰;如果返回值的类型为简单数据类型,只需在声明方法的前面加上相应的数据类型即可;同理,若需方法返回一个数组,则必须在该方法的前面加上数组类型的修饰符。见教材P113【例6.6】将一个矩阵转置后输出。,引用类型(类),方法返回值:数组,2019/5/16,50,/app6_6.java 返回值是数组类型的方法 public class app6_6 public static void main(String args)int a=1,2,3,4
29、,5,6,7,8,9; /定义二维数组int b=new int 33;trans pose=new trans(); /创建trans类的对象poseb=pose.transpose(a); /用数组a调用方法,返回值赋给数组bfor (int i=0;ib.length;i+) /输出数组的内容for (int j=0;jbi.length;j+)System.out.print(bij+ “ “ );System.out.print(“n“); /每输出数组的一行后换行 ,2019/5/16,51,class trans int temp;int transpose(int array)
30、 /返回值为二维整型数组for (int i=0;iarray.length;i+) /将矩阵转置for(int j=i+1;jarrayi.length;j+)temp=arrayij;arrayij=arrayji;arrayji=temp;return array; /返回二维数组 ,2019/5/16,52,作业:编写类的“拷贝构造方法”class A private int m; private int n; public A (int x, int y) 属性赋值 public A ( 参数 ) /拷贝构造方法 对象复制功能:新创建对象的属性值与已知对象一样 方法outPut()
31、输出对象属性值public static void main(String args) 用new A(100,200)生成对象p1;显示对象p1的属性值;用拷贝构造方法生成对象p2,使其属性与对象p1相同;显示p2属性值; ,参数传递,2019/5/16,53,this关键字,问题例:,this,若方法的形参与类的成员变量同名,方法体内如何操作成员变量?,class Fish String name;int age, weight;void setData(String name, int age, int weight) name=name; age=age; weight=weigth;
32、,this.name=name; this.age=age; this.weight=weight,2019/5/16,54,是例:,this,系统为每个实例方法(非static方法)提供的一个引用变量 (系统自动提供) (局部变量),直接使用无需定义,class Fish String name; int age, weight;void setData ( String n, int a, int w)name=n; age=a; weight=w; ,this. 系统自动添加,2019/5/16,55,值例:,this,所在对象的首地址。即:指向这个方法所在的对象。代表这个对象。,不能被
33、赋值,class A / 上例 Fish类 public static void main(String arg) Fish p1=new Fish();Fish p2=new Fish();p1.setData(“Golden”, 2 , 0.5);p2.setData(“Shark”, 10, 100); ,void setData ( String n, int a, int w) this. name=n; this. age=a; this. weight=w; ,2019/5/16,56,【例6.3】以圆柱体类Cylinder为例来介绍在类内部调用自己 的方法。,/app6_3.j
34、ava 在类内部调用方法 class Cylinder /定义Cylinder类 double radius;int height;double pi=3.14;double area() /定义返回值为double型的方法area (),计算底面积return this.pi* this.radius* this.radius;,this,2019/5/16,57,double volume() /定义返回值为double型的方法volume (),计算体积return this.area()*this.height; /在类内调用area()方法 /结束class Cylinder pub
35、lic class app6_3 /定义公共类 public static void main(String args )Cylinder volu;volu=new Cylinder(); /创建新的对象volu.radius=2.8; /赋值圆柱volu的底半径volu.height=5; /赋值圆柱volu的高System.out.println(“底圆半径=“+volu.radius);System.out.println(“圆柱的高=“+volu.height);,【例6.3】续,2019/5/16,58,System.out.print(“圆柱“);System.out.print
36、ln(“底面积=“+volu.area();System.out.println(“圆柱体体积=“+volu.volume(); ,【例6.3】续,程序运行结果如下: 底圆半径=2.8 圆柱的高=5 圆柱底面积=24.6176 圆柱体体积=123.088,2019/5/16,59,例e: 对错?作业:Circle类 成员变量double pi double radius (一份) (封装) 成员方法构造方法(成员变量初始化),this,public static void main (String args) System.out.println(this); ,方法Compare_1( )接
37、收一个Circle对象,如果该对象与本对象的首地址相同,返回真,否则返回假。 方法Compare_2( )接收一个Circle对象,比较该对象与本对象的成员变量radius的值是否相等,相等返回真,不相等返回假.,2019/5/16,60,6.5 匿名对象,当一个对象被创建之后,在调用该对象的方法时,也可以不定义对象的引用变量,而直接调用这个对象的方法,这样的对象叫做匿名对象。例如: Cylinder volu=new Cylinder(); volu.SetCylinder(2.5, 5,3.14); 改写为: new Cylinder().SetCylinder(2.5, 5,3.14); 则Cylinder()就是匿名对象。,2019/5/16,61,使用匿名对象通常有如下两种情况: 1如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。 2将匿名对象做为实参传递给一个方法调用。,2019/5/16,62,再见!,