580 likes | 774 Views
第 4 章 抽象、封装与类. 4.1 抽象、封装与类 4.2 Java 的类 4.3 类的修饰符 4.4 域 4.5 方法 4.6 访问控制符 4.7 小结. 4.1 抽象、封装与类. 4.1.1 抽象 1 概念 抽象是对具体对象(问题)进行概括。 ( 先注意问题的本质及描述,其次是实现过程或细节 ) 2 抽象分类 (1) 过程抽象 描述某类对象的共有的行为特征或具有的功能。 (2) 数据抽象 描述某类对象的属性或状态 ( 对象相互区别的物理量 ) 抽象的实现 —— 通过类的声明。. 举 例
E N D
第4章 抽象、封装与类 4.1抽象、封装与类 4.2Java的类 4.3 类的修饰符 4.4域 4.5 方法 4.6 访问控制符 4.7小结
4.1抽象、封装与类 4.1.1 抽象 1 概念 抽象是对具体对象(问题)进行概括。 (先注意问题的本质及描述,其次是实现过程或细节) 2 抽象分类 (1)过程抽象 描述某类对象的共有的行为特征或具有的功能。 (2)数据抽象 描述某类对象的属性或状态(对象相互区别的物理量) 抽象的实现——通过类的声明。
举 例 银行对核心任务的操作— 存取还款的金额、帐号、日期…… 抽象后属于:数据类型。 存款、取款、还款过程…… 抽象后属于:方法。 数据抽象: int HowMach, int N, int D 过程抽象: Setsave(), Setget(), Setsent ()
4.1抽象、封装与类 4.1.2 封装 1 概念 将抽象出的数据成员、过程方法有机结 合为一个整体。 2 优点 提高类或模块的可重用性、隐藏性。 这是面向对象程序设计的主要优点之一。
4.2 Java的类 Java的程序设计就是定义类的过程。 4.2.1 系统定义的类 系统定义好的类就是Java类库中的类。 根据实现功能不同,划分不同的集合,每个集合是一个包,合称为类库。 又称为:API---application program interface SUN 公司提供的类库称为基础类库JFC。
1有关包的解释 包:若干个扩展名为class的文件集合在一起就形成了包。 Java主包:Java 的一层包,名为java; Java主子包:Java的二层包,名为lang; Java标准的扩展包:名为javax,最多只有三层。 包是可以有任意多层子包。包和子包 的名字之间用点号隔开。 例:javax. swing.tree
Java.sun.com/j2se/1.4.1/docs/api/index.html 自学所有类库的查找方法 列出Java中所有软件包页面 软件包(总说明、包内容说明)页面: 接口Interfaces/类classes/异常Exceptions/错误Errors 所有不推荐使用类的功能页面提示。 说明有哪些软件包、类、方法等用了该类的任何一部分内容的页面。 类和接口页面: 最顶级的类为Object/直接继承的类是Panel/... 按字母顺序列出Java中的所有类、接口、构造方法、方法和域。 软件包、类和接口的层次图页面。 (比class页面详细) 参考资料: Java2 API大全 电子工业出版社
2常用的包简介 1) java.lang 2) java.lang.reflect 3) java.io 4) java.util 5) java.util.zip 6) java.awt 7) java.awt.image 8) java.awt.datatransfer 9) java.awt.event 1. 核心类库: 含数据类型、 基本数学函数、 字符串 、 处理、 线程、 异常处理类等 2.核心类库: 是反射对象工具, 监视正在运行的对象并获得它的构造函数、方法和属性。 • 3.标准I/O类库: • 基本I/O流、 • 文件I/O流、 • 过滤I/O流、 • 管道I/O流、 • 随机I/O流等。 4低级实用工具类库: 处理时间Date类 变长数组Vector类 栈Stack类 杂凑表HashTable类 5低级实用工具类库 实现文件压缩类 6.构建图形用户: 低级汇图操作 图形界面组件、 布局管理 界面用户交互、 事件响应等 7.构建图形用户 处理、操作网上图片的工具 8.构建图形用户 处理剪贴板、字符串发送器等 9.构建图形用户 Event类的扩充 处理不同类型的事件
2常用的包简介 10) java.applet 11) java.net 12) java.corba 13) java.corba.orb 14) java.rmi 15) java.rmi.reistry 16) java.rmi.server 17) java.security 18) java.security.acl 19) java.security.interfaces 20) java.sql 10. 实现运行于 Internet浏览器中的Java Applet的工具 类库。 11.网络功能类库低层网络通信编写FTP,Telnet等网上通信类访问网上资源进行CGI网关调用的类等。 12,13.其他面向对象语言开发的 部件。(可方便、动态地利用已经存在的软件) 14~16.远程方法调用用户程序可以在远程计算机(服务器)上创建对象,在本地计算机上使用该对象。 17~19.安全控制管理对程序加密把Java Applet 进行标记,使之具有与完整的Java程序有相同的安全性。 20. 访问各种数据库包JDBC。 可访问: Oracle, Sybase, DB2, SQLServer等
常用java子包汇总 包接口和类的用途 包 接口和类的用途 java.applet applet java.rmi 远程方法调用 java.awt 图形和图形用户接口 java.rmi.dgc 支持java.rmi java.awt.datatranster 剪切和粘贴功能 java.rmi.registry 同上 java.awt.event事件处理 java.rmi.server 同上 java.awt.image 图像处理 java.security 安全 java.awt.peer平台无关图形 java.security.acl 支持java.security java.beans软件组件 java.security.interfaces 同上 java.io输入输出 java.sql 数据库 java.lang 语言的核心功能 java.text国际化 java.lang.reflect映射(“自省”) java.util 各种工具 java.math任意精度算术运算 java.util.zip 压缩和解压缩 java.net 连网
常用javax子包汇总 包 包中接口和类的用途 javax.accessibility 判定技术 javax.swing “轻便”的图形和图形用户 javax.swing.border 专用边界 javax.swing.colorchooser 颜色选择 javax.swing.event 扩展java.awt.event的事件处理 javax.swing.filechooser 文件选择 javax.swing.plaf 可插入的外观和效果 javax.swing.plaf.basic 基本的外观和效果 javax.swing.plaf.metal 金属的外观和效果 javax.swing.plaf.multi 复合体的外观和效果 javax.swing.table 数据的表单表示 javax.swing.text 文本的表示和处理 javax.swing.text.html HTML文本 javax.swing.text.rtf RTF(Rich Text Format)文本 javax.swing.tree 数据的树型表示 javax.swing.undo 文本编辑中的撤消功能
重 点 使用系统定义类的三种方式 1 继承系统类 例:每个Java Applet的主类都是Java.applet包中 Applet类的子类。 2 直接使用系统类 例:字符界面系统标准输出的方法引用 System.out.println( ) 3 创建系统类的对象 例:图形界面接受输入时创建系统类的对象 TextField input
4.2.1系统定义类小结 使用系统类的前提条件: * 必须用import语句引入所用到的系统类等。 类库包中的程序都是字节码形式的程序,利用import语句将一个包引入到程序里来,就相当于在编译过程中将该包中所有系统类的字节码加入到用户的Java程序中,这样用户Java程序就可以使用这些系统及其类中的各种功能。
4.2 Java的类 4.2.2用户程序自己定义类 * 类有三中类型的成员:域、方法和构造器。 * 类的定义格式: modifiers class class-name { body } modifiers:public公有, abstract抽象, final最终 body: 是一系列的域声明、构造方法等。
简单应用举例----例4-1 class PhoneCard { long cardNumber; //域声明 private int password; double balance; String connectNumber; boolean connected; boolean performConnection(long cn, int pw) { if(cn==cardNumber && pw==password) { connected=true; return true; } else { connected=flase; return flase; } ① } double getBalance( ) { if(connected) return balance; else return –1; } ② void performDial( ) { if(connected) balance -=0.5; } ③ } (五个域,三个方法)
4.2.3创建对象与定义构造方法 1 创建对象 (1)用类名定义所引用的对象 格式:类名 对象名;(类变量的引用) 举例:Textfield input; (2)创建并初始化对象 格式:new 构造方法(实参表); 举例:new Textfield(10); (3)把new运算的返回值赋给引用的对象 格式:引用对象名=new 构造方法(实参表) 举例:input=new Textfield(10); 对象创建时的简化格式—上述三步汇总 类名 对象名=new 构造方法([实参表]); 举例:Textfield input=new Textfield(10);
创建对象举例 例4-1分析: 创建PhoneCard对象—myCard: PhoneCard myCard=new PhoneCard( ); myCard.cardNumber myCard.password myCard.balance myCard.connectNumber myCard.connected myCard.performConnection myCard.getBalance myCard.performDial myCard对象的域 myCard对象的方法
定义构造方法说明 2构造方法——constructor (1)为什么使用构造方法 目的:对声明的对象进行初始化。 (2)构造方法的特性 * 构造方法的方法名与类名相同; * 构造方法没有返回类型; * 构造方法的主要作用是完成对类对象的初始化; * 构造方法一般不能由被显式地直接调用; * 在创建一个类的新对象的同时,系统会自动 调用该类的构造方法为新对象初始化。
应用举例——例4-2(UsePhoneCard.java) public class UsePhoneCard { public static void main(String args[]) { PhoneCard myCard=new PhoneCard(12345678,1234,50.0, “300”); System.out.println(myCard.toString( )); } } //主方法定义① class PhoneCard { long cardNumber; private int passwor double balance; String connectNumber; boolean connected; ② PhoneCard(long cn, int pw,double b, String s) { cardNumber=cn; password=pw; if(b>0) balance=b; else System.exit(1); connectNumber=s; connected=false; } //构造方法③
void performDial( ) { if(connected) balance -=0.5; } ⑥ public String toString( ) { String s=“电话卡接入号:” connectNumber + “\n电话卡卡号:” +cardNumber + “\n电话卡密码:”+password +“\n剩余金额:”+balance; if(connected) return(s + “\n电话已接通。”); else return(s + “\n电话未接通。”); } } ⑦ boolean perormConnection(long cn, int pw) { if(cn==cardNumber && pw==password) { connected=true; return true; } else { connected=flase; return flase; } } ④ double getBalance( ) { if(connected) return balance; else return –1; } ⑤
4.3类的修饰符—modifiers 类的修饰符——有三种分两类: 访问控制修饰符—public公有类 它可以被任何程序包中的所有类所访问和使用; 非访问控制修饰符—abstract抽象类, final最终类。 4.3.1抽象类 概念:抽象类是指没有具体对象概念的类。 举例: (1)人类 (2)车类 (3)几何图形类 (4)电话卡类 4.3.2最终类 概念:最终类是指其类不能再有子类的类。
举例:电话卡及其子类的层次关系树 电话卡类 无卡号类 有卡号类 200卡 IC卡 磁卡 IP卡 校园201卡 • 说明: • 抽象类的abstract和最终类的final修饰符不能同 时修饰一个类; • 抽象类和最终类可以各自与其他的修饰符合用。
4.4域 概念:域是类和对象的静态属性。 域的表现形式: 基本数据类型变量、其他类的对象等。 1 简单域声明格式: modifiers type-name variable-name; modifiers:static, final, transient, volatile, public, protected, private—共7个。 type-name:boolean, byte, char, short, int, long, float, double
2域的修饰说明1 • 静态域 用static修饰符修饰的域是仅属于类的静态域。 特点:静态域是类的域,不属于任何一个类的具体对象。 例题4-3 • 静态初始化器 它是用关键字static引导的一对大括号括起的语句组。 说明:它不是方法,它只对自身进行初始化,类加载时 由系统调用执行。 例题4-4 继续
应用举例——例4-3 (TestStaticField.java) public class TestStaticField//第一个类主类的定义 { public static void main(String args[ ]) { PhoneCard200 my200_1=new PhoneCard200( ); //创建对象并初始化 PhoneCard200 my200_2=new PhoneCard200( ); //创建对象并初始化 my200_1.additoryFee=0.1; //访问类的静态域并赋值 System.out.println(“第二张200卡的附加费:”+my200_2.additoryFee); System.out.println(“200卡的附加费:”+PhoneCard200.additoryFee); } }
class PhoneCard200 //第二个类定义 { static String connectNumber= “200”; static double additoryFee; long cardNmuber; int password; Boolean connected; Double balance; } 返回
应用举例——例4-4 (TestStatic.java) public class TestStatic { public static voic main(String args[ ]) { PhoneCard200 my200_1=new PhoneCard200( ); PhoneCard200 my200_2=new PhoneCard200( ); System.out.println(“第一张卡的卡号:”+my200_1.cardNumber); System.out.println(“第二张卡的卡号:”+ my200_2.cardNumber); } }
class PhoneCard200 { static long nextCardNumber; //声明 static String connectNumber; static double additoryFee; long cardNumber; int password; boolean connected; double balance; static //初始化 { nextCardNumber=200180001; } PhoneCard200( ) { cardNumber=nextCardNumber++; //调用 } } 返回
2域的修饰说明2 • 最终域 概念:被修饰为final的常量标识符,在整个程序执 行过程中都不变。 注意: 1)需要说明常量的数据类型; 2)需要同时指出常量的具体取值; 3)因类对象的常量成员,其数值都固定一致, 为节省空间通常声明为static • 易失域 概念:被修饰为volatile的域可同时被几个线程所控 制和修改。因此,它多用以修饰接受外部输 入的域。
补练习:StaticAndInstance.java静态成员变量和实例成员变量的区别:补练习:StaticAndInstance.java静态成员变量和实例成员变量的区别: public class StaticAndInstance //类定义 { static int xStatic=5; //声明静态成员变量 int xInstance; //声明实例成员变量 static int yStatic; //声明静态成员变量 static //静态初始化器 { System.out.println("Inside Static:\n xStatic=" + xStatic + "\t yStatic="+ yStatic); xStatic++; yStatic=9; } StaticAndInstance() { } //无参数的构造函数,方法体为空 StaticAndInstance(int k) //带参数的构造函数 { xInstance=k; }
public static void main(String args[ ]) //主函数 { int i=1; //定义一个自动变量,记录输出显示序号“类名.静态成员变量名” System.out.println("("+i+++")Via the class name to reference xStatic " + StaticAndInstance.xStatic); //第1次调用输出“类名.静态成员变量名” StaticAndInstance obj0=new StaticAndInstance( ); StaticAndInstance obj1=new StaticAndInstance(4); StaticAndInstance obj2=new StaticAndInstance(6); System.out.println("("+i++ +")Via the class access xStatic=" +obj1.xStatic+"\n yStatic="+obj1.yStatic); //2次调用“对象名.变量名” System.out.println("("+i++ +")Via the other class access xStatic=" +obj2.xStatic+"\n yStatic="+obj2.yStatic); //3次调用“对象名.变量名” System.out.println("("+i++ +") xInstance of obj0="+obj0.xInstance +"\t xInstance of obj1="+obj1.xInstance +"\t xInstance of obj2="+obj2.xInstance); } //第4次调用:“对象名.实例变量名” } //用new创建三个对象
4.5方法 简单方法定义格式: modifiers return-type method-name(parameter-list) { boday } <访问控制符><修饰符><返回类型>方法名(参数表) { 方法体 }
例题引入:完全数判断(例3-10 PerfectNum.java) public class PerfectNum { public static void main(String args[ ]) {int count=1; for(int i=1; i<1000; i++) { int y=0; for(int i=1; i<x; i++) if(x%i==0) y+=j; if(y= =i) {System.out.print(i+String.valueOf('\t')); count++; if(count%3==0) System.out.println(); } } } }
应用举例—例3-10 替换4-5 static boolean isPerfect(int x) { int y=0; for(int i=1; i<x; i++) if(x%i==0) y+=i; if(y==x) return true; else return false; } public class PerfectNum { public static void main(String args[]) { int count=1; for(int i=1; i<1000; i++) { if(isPerfect(i)) {System.out.print(i+String.valueOf('\t')); count++; if(count%3==0) System.out.println(); } } }
1 抽象方法 概念: 由修饰符abstract修饰且仅有方法头。 即是一种没有方法体的类定义。 优点: 可以隐藏具体的细节信息,使调用该方法的程序不必过分关注类及其类内部的具体情况。
主类 抽象类 子类 子类 应用举例—例4-6TestAbstract.java 程序分析: 程序定义了四个类:主类、抽象类、子类1和子类2; 执行第15行——double TimeLeft()方法; 执行方法中循环的21行performDial()方法时, 调用子类1中其方法第47行, 然后再执行: Times++ balance=balance-0.6 直到balance<=0时截止,返回:Times-1值。 执行第15行——double TimeLeft()方法; 执行方法中循环——21行performDial()方法, 调用子类1中其方法第58行, 然后再执行:Times++ balance=balance-0.9 直到balance<=0时截止,返回:Times-1值。 第一次输出 第二次输出
Public class TestAbstract { public static void main(String args[]) { PhoneCard200 my200=new PhoneCard200(50.00); ICCard myIC=new ICCard(50.0); System.out.println(“200卡可以拨打”+my200.TimeLeft()+ “次电话”); System.out.println(“IC卡可以拨打”+myIC.TimeLeft()+ “次电话”); } } abstract class PhoneCard { double balance; abstract void performDial(); • double TimeLeft() • { double current=balance; times=0; do { performDial(); times++; }while(balance>=0); balance=current; return times-1; } } 测试电话卡中余额
28 class PhoneCard200 extends PhoneCard // PhoneCard的子类 30 { static long nextCardNumber; static final String connectNumber="200"; static double additoryFee; long cardNumber; int password; boolean connected; 37 static //静态初始化器,设置附加费初值 { nextCardNumber=20018001; additoryFee=0.1; } 41 PhoneCard200(double ib) //构造方法:指定新电话卡金额 { cardNumber=nextCardNumber++; balance=ib; } 47 void performDial() //方法:重新定义父类中的抽象方法, { balance-=0.5+additoryFee; } //扣除通话费用并加上附加费,每次-0.6 } 52 class IC_Card extends PhoneCard // PhoneCard的子类 { IC_Card(double ib) //构造方法:指定新电话卡金额 { balance=ib; } 58 void performDial()//方法:重新定义父类中的抽象方法, { balance-=0.9; } //扣除通话费用,每次-.9 }
2 静态方法 用static修饰符修饰的方法,是属于整个类的类方法; 未用static修饰符修饰的方法,是某个具体类对象或实例的方法。 static方法的三重含义: (1) 调用这个方法时,应用类名做前缀,而不是某一 个具体对象名; (2)static方法不被任何一个对象专有。 (3) 因static方法属于整个类,所以它不能针对某个 对象的成员进行操作和处理;只能对整个类的成 员变量进行操作。
静态方法简单举例: 在PhoneCard200中若需要修改附加费时定义的静态方法: static void setAdditory(double newAdd) { if(newAdd>0) additoryFee=newAdd; }
3 最终方法 用final修饰符所修饰的类的方法, 即功能和内部语句不能更改的方法。 注意:被private修饰的方法和在final类中 的方法都被认为是最终方法。 重载:类对自身已有的同名方法的重新定义。
4 本地方法 用native修饰符所声明的类的方法,该方法由其他编程语言实现。 5同步方法 synchronized 修饰的方法是一个类的方法。 对系统类中的对应的对象进行加锁。 (多线程中学习)
4.6 访问控制符 类的访问控制:1 public ; 2 缺省 域的访问控制: 1 缺省__被同一包中其他类引用,又为包访问性。 2 public :(1)类自身的引用; (2)同一个包内的该类的子类。 3 protected:(1)类自身的引用; (2)同包其他类的引用; (3)其他包该类的子类引用。 4 private protected:(1)类自身的引用 (2)任意包中该类的子类。
A:所有类 C:所有 子类 B:包中的类 E:包中子类 D:本类 程序中的访问控制区域 类 公有 友元 属性与方法 public 缺省 public A B protected B+C B 缺省 B B private protected C+D E+D private D D
//可由本类中的对象成员引用 即:对象.方法所引用 补充例题:分析例题访问的描述情况 (例题1) class Report { void qenerateReport( ) { doHeader( ); doBody( ); doFooter( ); } private void doHeader( ){ } private void doBody( ){ } private void doFooter( ){ } } //可由包中其他各类引用
补充例题:分析例题访问的描述情况 (例题2) public class MathTools { public double cube(double n) { return n*n*n; } public double square(double n) { return n*n; } } //所有包、包中所有类和本类可引用
补充例题:分析例题访问的描述情况 (例题3) class Employee { private double hoursWorked; private double hourlyRate; protected double computeSalary( ) { return hoursWorked * hourlyRate; } } //Employee包中所有类和它任意保重所有的子类均可引用
应用举例—例题4-7 AccessControl.java import java.applet.Applet; import java.awt.*; public class AccessControl extends Applet { ClassBeAccessed c=new ClassBeAccessed(); subClass sc=new subClass(); PackageClass ic=new PackageClass(); public void paint(Graphics g) { g.drawString("Self Accessible:",10,20); g.drawString(c.toString(),20,35); g.drawString("Sub Accessible:",10,55); g.drawString(sc.AccessDirectly(),20,70); g.drawString("Package Accessible:",10,90); g.drawString(ic.AccessDirectly(),20,105); g.drawString("Access using public method:",10,125); g.drawString(sc.AccessCls(),20,140); g.drawString(ic.AccessCls(),20,155); } }
class ClassBeAccessed { public String m_PublicProperty; String m_FriendlyProperty; protected String m_ProtectedProperty; private String m_PrivateProperty; ClassBeAccessed() { m_PublicProperty=new String("Public"); m_FriendlyProperty=new String("Friendly"); m_ProtectedProperty=new String("Protected"); m_PrivateProperty=new String("Private"); } public String toString() { return(m_PublicProperty+";"+m_FriendlyProperty+";" +m_ProtectedProperty+";"+m_PrivateProperty+";"); } }