370 likes | 549 Views
第 3 讲 类和对象. 3.1 类的定义 3.2 类的实例化 3.3 类的组织 3.4 实例分析. 本章要点. 理解类和对象之间的关系 熟练掌握类的设计方法、对象的使用方法 熟练运用实例成员和类成员编写程序. 3.1 类的定义. 3 . 1 . 1 类和对象的关系 类是对具有相同属性和方法的一组相似对象的抽象,或者说类是对象的模板。类是 Java 的核心,也是 Java 的基本单元。. 对象. 对象是某个类的实例,其变量表示属性,方法表示功能, Java 正是通过类和对象的概念来组织和构建程序的。
E N D
第3讲 类和对象 • 3.1 类的定义 • 3.2 类的实例化 • 3.3 类的组织 • 3.4 实例分析
本章要点 • 理解类和对象之间的关系 • 熟练掌握类的设计方法、对象的使用方法 • 熟练运用实例成员和类成员编写程序
3.1 类的定义 • 3.1.1类和对象的关系 • 类是对具有相同属性和方法的一组相似对象的抽象,或者说类是对象的模板。类是Java的核心,也是Java的基本单元。
对象 • 对象是某个类的实例,其变量表示属性,方法表示功能,Java正是通过类和对象的概念来组织和构建程序的。 • 封装、继承、多态是面向对象编程中采用的三大技术。
3.1.2 类的定义格式 • 1.类的声明格式 • 类的声明格式如下: • [修饰符] class <类名> [extends 父类名] [implements 接口名]{ • 类主体 • } • 其中,class是定义类的关键字,<类名>是所定义的类的名字,extends表示该类继承了它的父类,父类名指明父类的名称,implements表示类所实现的接口,若实现多个接口则用逗号隔开。
2.类主体设计 • Java的类包括变量和方法,分别叫做类的成员变量和成员方法。因此,类主体的设计主要是成员变量的设计和成员方法的设计两个部分。 • 声明成员变量的格式为: • [修饰符] <变量类型> <变量名> • 声明成员方法的格式为: • <修饰符> <返回值类型> <方法名> ( [参数列表] ) [ throws <exception> ] • { • 方法体 • }
例3.1 定义一个求圆面积的类 • public class Circle { • private double radius; • private double area; • final double pi=3.14; • public void setRadius(double r) { • radius=r; • } • public double calculateArea( ) { • return pi*radius*radius; • } • }
3.2 类的实例化 • 3.2.1 创建对象 • 创建对象包括对象声明和对象初始化两个部分。通常这两部分是结合在一起的,即定义对象的同时对其初始化,为其分配空间,并进行赋值。其格式为: • <类名> <对象名> = new <类名> ( [ <参数列表 > ] ) • 例如,创建例3.1中Circle类的一个对象可以写成: • Circle mycircle=new Circle();
3.2.2使用对象成员 • 对象的使用通过成员运算符“.” 实现对变量的访问和方法的调用。通常使用的格式为: • 对象名.成员变量名 • 对象名.成员方法名([ <参数列表> ]) • 例如: • mycicle.radius=5; //将mycicle的radius赋值为5 • mycicle.calculateArea(); //调用mycirlce的calculateArea方法求圆的面积 • 同类的对象之间也可以进行赋值,这种情况称为对象赋值。例如: • Circle anothercircle; • anothercircle=mycircle;
对象赋值 • 和变量赋值不一样,对象赋值并不是真正把一个对象赋给另一个对象,而是让一个对象名存储的对象首地址和另一个对象名存储的对象首地址相同。换句话说,对象间的赋值实际上是对象首地址的赋值。
例 3.3 设计类Number,测试对象间的赋值 • class Number{ • int i; • public static void main (String [ ] a){ • Number n1=new Number( ); • Number n2=new Number( ); • n1.i=9; • n2.i=47; • System.out.println("n1.i="+n1.i+"\t\t"+"n2.i="+n2.i); • n1=n2; • System.out.println("n1.i="+n1.i+"\t\t"+"n2.i="+n2.i); • n1.i=27; • System.out.println("n1.i="+n1.i+"\t\t"+"n2.i="+n2.i); • }}
1.访问控制修饰符 • 访问控制修饰符说明类或类的成员的可访问范围,用public修饰的类或成员拥有公共作用域,表明此类或类的成员可以被任何Java中的类所访问,是最广泛的作用范围。用protected修饰的变量或方法拥有受保护作用域,可以被同一个包中所有的类及其他包中该类的子类所访问。用private修饰的变量或方法拥有私有作用域,只能在此类中访问,在其他类中,包括该类的子类中也是不允许访问的,private是最保守的作用范围。没有使用任何修饰符的,拥有默认访问权限(也称友好访问权限),表明此类或类的成员可以被同一个包中的其它类访问。
1.访问控制修饰符 • class FieldTest{ • private int num=5; //私有作用域,本类可见 • public int get( ){ //公共作用域 • return num; // get 方法返回成员变量num的值 • } • } • class Test{ • public static void main(String [ ] args){ • FieldTest ft=new FieldTest( ); • int t=ft.get( ); //正确访问 • //int s=ft.num; //不能访问FieldTest类中私有成员变量num • System.out.println("t=" +t); • //System.out.println(s); • } • }
2.类型修饰符static • 在一个类中,使用static修饰的变量和方法分别称为类变量(或称静态变量)和类方法(或称静态方法),没有使用static修饰的变量和方法分别称为实例变量和实例方法。 • 类成员属于这个类而不是属于这个类的某个对象,它由这个类所创建的所有对象共同拥有。任何一个该类的对象改变了类成员,则对其他对象而言该类成员会发生同样的改变。 • 对于类成员,既可以使用对象进行访问,也可以使用类名直接进行访问,并且在类方法中只能访问类成员,而不能访问实例成员。
例3.5 定义类SaticTest,测试对实例成员和类成员的访问形式。 • public class StaticTest{ • static int i=1; • int j=1; • static void printStatic( ){ • System.out.println("i="+i); • //System.out.println("j="+j); //非法访问 • } • void print(){ • System.out.println("i="+i); • System.out.println("j="+j); • } • public static void main(String [ ] args){ • StaticTest.printStatic( ); • //StaticTest.print( ); //非法访问 • StaticTest.i=2; • //StaticTest.j=2; //非法访问 • StaticTest st=new StaticTest( ); • st.i=3; • st.j=3; • st.print( ); • st.printStatic( ); • }}
例3.6 测试类变量与实例变量的不同。 • public class StaticVar{ • int i=0; • static int j=0; • public void print( ){ • System.out.println("i="+i); • System.out.println("j="+j); • } • public static void main(String [ ] args){ • StaticVar sv1=new StaticVar( ); • sv1.i++; • sv1.j++; • sv1.print(); • StaticVar sv2=new StaticVar( ); • sv2.print(); • } • }
3.3类的组织 • 3.3.1 包的概念 • 包是Java提供的文件组织方式。 • 一个包中可以包括很多类文件,包中还可以有子包,形成包等级。 • 使用包不仅方便了类文件的管理,而且扩大了Java命名空间。不同的程序员可以创建相同名称的类,只要把它们放在不同的包中,就可以方便的区分,不会引发冲突。
3.3.2 创建包 • 创建包的语法格式为: • Package <包名>; • 例如:package myPackage; • 也可以创建包的层次。 • 例如:package myPackage .secondPackage; • 需要注意的是,package语句作为一个Java源文件的第一句 ,并且只允许出现一句 。
例3.7 将HelloWorld程序放入MyPackage中。 • package myPackage; • public class HelloWorld{ • public static void main(String [ ] args){ • System.out.print("Hello World!"); • } • }
3.3.3 访问包 • 1.目录布局及CLASSPATH环境变量 • 一旦一个类有了它的包,在访问时就需要指明类的路径,以便能够找到该类。 • 如:java myPackage. HelloWorld • 另外一个方法就是改变默认的类路径变量CLASSPATH。 • 例如,HelloWorld.class文件所在的文件夹为C:\myjava\myPackage下,那么可以设置类路径为: • set CLASSPATH=.;C:\myjava
2.import语句 • Java使用import语句来引入特定的类甚至是整个包。 • import声明的通用形式: • import pkg1[.pkg2].(classname|*);
3.访问保护 • 类、包都是用来封装变量和方法、容纳名称空间的。包就像盛装类和下级包的容器,类就像是数据和代码的容器。访问控制修饰符确定访问限制。
例3.8 下面的例子演示了包的保护作用。 • //A.java文件 • package mypackage; • public class A{ //公共作用域 • int num; //包的作用域 • public int get( ){return num;} //公共作用域 • } • //B.java文件 • package anotherpackage; • import mypackage.A; • class B{ //包的作用域 • A mya = new A ( ); //正确访问 • void m( ){ • int t= mya.get( ); //正确访问 • int s = mya.num; //错误,num是包的作用域,不能访问 • }}
3.4 实例分析 • 例3.9设计一个电视机类,成员变量包括电视机编号、生产厂家、品牌名称、大小、开关状态,并可以对其进行相应操作,如打开电视、提高/降低音量、更换频道等。 • 电视机编号由生产日期和生产编号构成,如2005年4月12日生产的第一台电视的编号为2005041201,第二台为2005041202,该编号自动生成。将该类放入自己的包中,并进行测试。 • 代码如下:
3.4 实例分析 • package mypackage.tvset; //定义包mypackage.tvset • import java.util.Date; //引入java.util.Date类,用于获得当前日期 • public class TvSet{ • private static int number; //电视机编号 • private int tvnumber; • private final String manufacturer="职业学院设备厂"; //生产厂家 • private final String brandname="学院牌"; //电视机品牌名 • private int size; //电视机尺寸 • private String switchstate="关闭"; //电视开关状态 • public TvSet (int size){ //构造函数 • this.size=size; • setNumber ( ); • tvnumber=number; • System.out.print("由"+manufacturer+"制造的"+brandname+size+"吋电视已被制造。"); • System.out.println("该电视的编号为"+tvnumber); • }
3.4 实例分析 • private static void setNumber( ){ //设置电视机编号 • String datenumber; • Date d=new Date( ); • String day=Integer.toString(d.getDate( )); //获取当前日期 • String month=(d.getMonth()<9)?"0"+Integer.toString(d.getMonth()+1):Integer.toString (d.getMonth( )+1); • String year=Integer.toString(d.getYear ( )+1900); • datenumber=year+month+day; • number= (number==0)?Integer.parseInt(datenumber+"01"):number+1; • //生成电视机编号 • }
3.4 实例分析 • public void openTv( ){ //打开电视 • switchstate="打开"; • System.out.println("电视已被打开"); • } • public void closeTv ( ){ //关闭电视 • switchstate="关闭"; • System.out.println("电视已被关闭"); • } • public void changeChannel (String s){ //更换频道 • System.out.println("电视已被切换到"+s+"频道"); • } • public void heightenVolume ( ){ //增大音量 • System.out.println("电视音量被提高"); • } • public void lowerVolume ( ){ //降低音量 • System.out.println("电视音量被降低"); • } • public int getSize ( ){ //获取电视机尺寸 • return size; • } • public String getSwitch ( ){ //获取电视机开关状态 • return switchstate; • } • public int getTvnumber ( ){ //获取电视机编号 • return tvnumber; • } • }
3.4 实例分析 • class Test{ //运行测试 • public static void main(String [ ] args){ • TvSet tv1=new TvSet (24); • TvSet tv2=new TvSet (29); • TvSet tv3=new TvSet (34); • tv1.openTv ( ); • tv1.changeChannel ("CCTV5"); • tv1.heightenVolume ( ); • System.out.println ("tv1处于"+tv1.getSwitch ( )+"状态"); • System.out.println ("tv2处于"+tv2.getSwitch ( )+"状态"); • System.out.println ("tv2的大小为"+tv2.getSize ( )+"吋"); • System.out.println ("tv2的编号为"+tv2.getTvnumber ( )); • System.out.println ("tv3的编号为"+tv3.getTvnumber ( )); • } • }}