55
第4第 第第第 Java Software Solution Foundations Program Design

第 4 章 编写类

  • Upload
    macon

  • View
    77

  • Download
    0

Embed Size (px)

DESCRIPTION

第 4 章 编写类. Java Software Solution Foundations Program Design. 类和对象. 对象表示现实世界中某个具体的事物 抽象是从特定的实例中抽取共同的性质以形成一般化概念的过程 对象具有两方面的含义: 在现实世界中: 是客观世界中的一个实体 在计算机世界中: 是一个可标识的存储区域. 类和对象. 封装的实体 = 数据 + 方法. 数据或变量. 类是具有共同属性和行为的对象的抽象 类可以定义为数据和方法的集合 类也称为模板,因为它们提供了对象的基本框架. 类. 方法. 实例化. 抽象. - PowerPoint PPT Presentation

Citation preview

Page 1: 第 4 章   编写类

第 4 章 编写类

Java Software Solution Foundations Program Design

Page 2: 第 4 章   编写类

类和对象

对象表示现实世界中某个具体的事物抽象是从特定的实例中抽取共同的性质以

形成一般化概念的过程对象具有两方面的含义:

在现实世界中:在现实世界中:是客观世界中的一个实体是客观世界中的一个实体

在计算机世界中:在计算机世界中:是一个可标识的存储区域是一个可标识的存储区域

Page 3: 第 4 章   编写类

类和对象

• 类是具有共同属性和行为的对象的抽象

• 类可以定义为数据和方法的集合

• 类也称为模板,因为它们提供了对象的基本框架

对象

抽象

实例化

属性或状态

操作或行为

数据或变量

方法

封装的实体 = 数据 + 方法

Page 4: 第 4 章   编写类

创建类

class name { type variable1; … type variableN;  type methodname1(parameter-list){ // 方法体 } … type methodnameN(parameter-list){ // 方法体 }}

在类中,属性是通过成员变量体现的,而操作是用成员函数(又称为

方法)实现的。

Java 中定义类的通用格式:

成员变量(对象属性)

成员方法(对象行为或操作)

Page 5: 第 4 章   编写类

定义方法

• 定义方法的一般格式:

[access] type methodname1([parameter-list]){ // 方法体}

发往某个对象的消息对应于一个方法调用。作为对消息的响应,对象将执行一个类似于过程体的方法。方法是

包含在类中的函数。

方法名称返回类型修饰符,可选

参数列表,可选

• 举例:public void setdate(int day, int month, int year){

day=23; month=7; year=2003;} 示例 2FruitDemo.java

Page 6: 第 4 章   编写类

对象作为参数

class Test{ int a,b;  Test(int i,int j) { a=i; b=j; } // 可以在函数中改变对象状态 void change(Test obj)

{ obj.a=50; obj.b=40; }

}

当对象作为函数参数时,在函数中只能改变该对象的状态,但不能改变

该对象的引用

void swapobj(Day x,Day y){ Day temp=y; y=x; x=temp;}

引用本身按值传递

Day

2002,5,30

Day

2003,7,23

obj1

obj2

x

y

调用 swapobj(obj1,obj2)

改变对象状态

x

y

Page 7: 第 4 章   编写类

this 引用public class PassTest {

int x;

PassTest(int x) {

this.x=x;

}

public void passingValue(){

System.out.println(“x 等于 " +x); }

public static void main(String args[]) {

PassTest test = new PassTest(10);

test.passingValue();

}

}

关键字 this 与对象关联它用于指示当前对象

指明此对象的变量 x 应赋值为通过构造函数传递的自变量 x

的值。

Page 8: 第 4 章   编写类

简单访问控制 - private 和 public

• public 声明的数据成员和成员函数可从类外部的任何地方访问。

• 而 private 数据将被隐藏,在类外不可见,这就实现了数据封装的思想。

• 要从类外操纵 private 成员,只能通过类的 public或 protected 成员来实现。

Page 9: 第 4 章   编写类

方法重载( overloading )

• 方法重载是 Java 实现面向对象的多态性机制的一种方式

• 同一个类中多个方法有相同的名字,不同的参数列表,这种情况称为方法重载。

• 返回类型不同并不足以构成方法重载。• 当重载方法被调用时,编译器根据参数的类型

和数量来确定实际调用哪个重载方法的版本。

Page 10: 第 4 章   编写类

方法重载示例class Calculation { public void add( int a, int b) { int c = a + b; System.out.println(" 两个整数相加得 "+ c); } public void add( float a, float b){ float c = a + b; System.out.println(" 两个浮点数相加得 "+c); } public void add( String a, String b) { String c = a + b; System.out.println(" 两个字符串相加得 "+ c); }}

class CalculationDemo { public static void main(S

tring args[]) {Calculation c = new Calculation();c.add(10,20);c.add(40.0F, 35.65F);

c.add(" 早上 ", " 好 "); }} 编译器决定

调用版本

Page 11: 第 4 章   编写类

构造函数• 构造函数名称与类名称相同• 构造函数没有返回类型• 其任务是在创建对象时初始化其内部状态class Fruit { boolean seedLess; boolean seasonal; float price; Fruit(boolean seed, boolean season, float p) { seedLess = seed; seasonal = season; price = p; } }

Page 12: 第 4 章   编写类

创建对象

• 使用下列语法可创建对象: new 构造函数• 关键字 new 通常称为创建运算符,用于分配对

象内存,并将该内存初始化为缺省值。• 一旦 new 完成分配和初始化内存,它就将调用

构造函数来执行对象初始化。

当创建一个类时,只是创建了一种新的数据类型。对象是类的一个实例。

class FruitDemo { public static void main(String args[]){ Fruit f = new Fruit(true,false,50.0F); }} 创建对象

Page 13: 第 4 章   编写类

缺省初始值

• Java 保证了在任何代码使用该内存之前,已至少将内存初始化为可预知的缺省值

类型 缺省值 类型 缺省值byte (byte)0 char '\u0000 '

short (short)0 float 0.0F

int 0 double 0.0D

long 0L 对象引用 null

boolean false

Page 14: 第 4 章   编写类

重载构造函数

• Java 为每一个类自动提供缺省构造函数• 缺省构造函数将成员变量的值初始化为

缺省值• 一旦创建了自己的构造函数,缺省的构

造函数将不复存在。• 重载构造函数提供了一组创建对象的方

式,可以根据需要决定是否带初始参数。

public class constructOverload { int x; constructOverload() { x=0; System.out.println(" 不带参数的构造函数 "); }  constructOverload(int x){ this.x=x; System.out.println(" 带一个参数的构造函数 "); } }

Page 15: 第 4 章   编写类

继承

• 被继承的类称为父类• 继承父类的类称为子类• 执行继承时,子类将获得父类的属性,并具有自身特有的属性。

继承是面向对象编程技术的一块基石,它允许创建分等级层次的类。运用继承,可以创建一个通用类定义一系列一般特性。该类可以被更具体的类继承

Emoloyee 类: name sex

Worker 类: category dressAllowance

Officer 类: empClass vehicle

职员类,具有姓名和性别两个属性

工人类,继承了父类的姓名和性别属性外还包含类别和是否有服装津贴属性

主任类,还包含级别和是否配备交通工具属性

Page 16: 第 4 章   编写类

extends 关键字

• extends 关键字用于继承类。• 声明一个继承父类的类的通常形式如下: class subclass-name extends superclass-name { // 类体 }

没有 extends ,默认父类为 Object 只能有一个父类,即单继承 子类继承父类的全部成员

注意

Page 17: 第 4 章   编写类

super 关键字• super 关键字用来解决如何直接访问或初始化从

父类继承来的属性。• super 有两种通用形式:调用父类的构造函数、

用来访问被子类的成员覆盖的父类成员。 • 它用在对象的构造函数中,将构造细节通过继承

链往上传递。• super() 必须是在子类构造函数中的第一个执行

语句。

Page 18: 第 4 章   编写类

继承示例class Employee { String name; // 姓名 char sex; // 性别 Employee(String n, char s){ name = n; sex = s; } public String getName() { return name; } public char getSex(){ return sex;}}

class Worker extends Employee { char category;//类别 boolean dressAllowance; // 是否提供服装津贴 Worker(String n,char s,char c,boolean d){ super(n,s); category = c; dressAllowance = d; } public char getCategory(){return category;} public boolean getAll(){ return dressAllowance; }}

class InheDemo { public static void main(String args[]) { Worker w = new Worker("M.John",'M','B',true); System.out.println(" 工人信息 "); System.out.println(" 姓名 : "+w.getName()); System.out.println(" 性别 : "+w.getSex()); System.out.println(" 类别 : "+w.getCategory()); if(w.getAll()) System.out.println(" 提供服装津贴 "); else System.out.println(“ 未提供服装津贴” ); }}

Page 19: 第 4 章   编写类

instanceof

class Student {}class Graduate extends Student {}class UndergraduateStudent extends Student {}public class st { public static void main(String []args) { UndergraduateStudent s1 = new UndergraduateStudent(); Graduate s2=new Graduate(); Student x; x=s1; if (x instanceof UndergraduateStudent) System.out.println(“x 是 UndergraduateStudent 类 的 实

例。” ); else System.out.println(“x是 Graduate 类的实例。” ); }}

instanceof 测试第一个参数的运行时类型是否为与第二个参数兼容的赋值。

x 在运行时指向s1 ,所以 if 语句条件返回 true

Page 20: 第 4 章   编写类

类型转换

• 执行自动类型转换需要两个条件: 接受转换的两种类型是兼容的 目的类型数的范围比源类型的大

• 强制类型转换语句的通用格式如下: (目标类型) value

UndergraduateStudent s1 = new UndergraduateStudent(); Graduate s2=new Graduate();Student x;x=s1;Graduate s3=new Graduate();if (x instanceof Graduate) s3= (Graduate)x;

注意:从父类到子类的转换,建议在转换前判断父类是否指向

子类的对象

Page 21: 第 4 章   编写类

Object 类

• Object 类是类体系结构的根• Java 系统中的每个类都是 Object 类直接或

间接的子类• Object 类包括在 java.lang 包中• 此类定义了所有对象都具备的基本状态和行

为• 可以用类型为 Object 的变量来引用任意类型

的对象

Page 22: 第 4 章   编写类

equals()

• 用于比较两个对象是否相等,相等返回 true• Object 类中提供的 equals 方法使用恒等函数来确

定对象是否相等• Object 类中实现的 equals 方法只能用来判断两个不

同的对象是否指向同一个内存区域• 子类一般通过覆盖 Object 的 equals 方法实现有意义

的测试,可以实现:若同一类型的两个不同对象包含相同的信息即返回 true

Integer one = new Integer(1);Integer anotherOne = new Integer(1);if (one.equals(anotherOne)) System.out.println(" 对象相等 ");

Page 23: 第 4 章   编写类

toString()

• toString 用于返回对象的字符串表示。 • 建议所有子类都覆盖此方法。• 使用“ +” 运算符将对象同一个字符串连接, Java 编

译器会自动调用 toString 方法,获取对象的字符串表现形式。

Derived d = new Derived();System.out.println("Derived 的 toString() : " + d);

自动调用 d.toString方法,获取对象的字

符串表示形式

Page 24: 第 4 章   编写类

方法覆盖( override )

• 方法覆盖是 Java 实现多态性机制的另一种方式。• 在类层次结构中,如果子类中的一个方法与父类中

的方法有相同的方法名并具有相同数量和类型的参数列表,这种情况称为方法覆盖。

• 当一个覆盖方法通过父类引用被调用, Java 根据当前被引用对象的类型来决定执行哪个版本的方法。

• 可以通过 super 关键字调用直属父类中被覆盖的方法版本。

Page 25: 第 4 章   编写类

方法覆盖示例class SuperClass { int a; SuperClass(){ a = 10; } public void printA(){System.out.println(" 父类中 a ="+a);}}class SubClass extends SuperClass { int a; SubClass(int a){ this.a = a; } public void printA(){ System.out.println(" 子类中 a = "+a); }}

public class OverrideDemo { public static void main(String args[]) { SuperClass s1 = new SubClass(10); s1.printA(); }} 将调用子类的 printA 方

Page 26: 第 4 章   编写类

• 在 Java 中,包主要有以下用途 : 包允许将类组合成较小的单元 有助于避免命名冲突 包允许在更广的范围内保护类、数据和方法

• 包可以是类、接口和子包的集合

Page 27: 第 4 章   编写类

创建包

package mypackage ;

public class Calculate

{

public int add(int x, int y)

{

return( x + y ) ;

}

}

在 Java 中,包用下面的方式来创建包:

package package_name ;

mypackage

calculate

Page 28: 第 4 章   编写类

创建包 ( 续 )

当创建一个包时,应注意任何创建包的语句应放在导入包的语句前创建包的时候,必须在 import 语句之前编写包声明如果需要从外部访问包的成员类,则要将其定义为 public

正确使用格式 错误使用格式

package mypackage ;

import java . io;

import java . io;

package mypackage ;

Page 29: 第 4 章   编写类

编译包——将 .class放在指定的包下

javac -d c : \ JavaProgs Calculate.javajavac -d c : \ JavaProgs Calculate.java

JavaProgs

mypackage

Calculate .

Class

用 -d 选项,在命令行下执行上面的语句,编译器将在您当前的文件夹(假设为 JavaProgs )下产生一个文件夹 mypackage 并把 Calculate.class 存放在该文件夹下

包用文件夹来表示,实质上就是一个路径

Page 30: 第 4 章   编写类

使用包

为了计算两个整数之和,我们不需要专门写计算和的代码我们可导入包 “mypackage” ,并使用其中的 public int add(int x, int y) 方法来计算

计算两个数之和的方法 : public int add(int x, int y)

Calculate 类

其他用于计算的方法 :

Page 31: 第 4 章   编写类

使用包中的成员 直接引用

如果使用了不同包中的类,而未使用该包的导入语句,则需要使用带有包名称的类名称

class Demo{ mypackage.Calculate calc=new mypackage.Calculate();

… … } 导入包中的类 导入包

// import mypackage. *;import mypackage.Calculate; class Demo{Calculate calc=new Calculate();

… …}

Page 32: 第 4 章   编写类

使用包 归纳几种使用包的方式:

导入要使用的类 import mypackage.Calculate;

导入整个包 import mypackage.*;

直接 引用 mypackage.Calculate calc=new mypackage.Calculate();

推荐使用前两种方式

Page 33: 第 4 章   编写类

编译使用包的 .java文件——带参数 classpath

javac -classpath c : \ JavaProgs PackageDemo.java

上述编译命令显式指定编译器按照 classpath 的内容搜索编译资源

classpath 中各项条目路径的顺序是非常重要的,JVM按照所提及的顺序搜索类路径中的条目寻找类,直到找到一个类为止

Page 34: 第 4 章   编写类

编译使用包的 .java文件—— classpath环境变量

如果不想在编译命令中显式指定 classpath 参数,可以设置 classpath 环境变量

classpath 变量的设置方法: 控制面板 - 系统 -高级 -环境变量 - 系统变量 -修改或新增 c

lasspath 变量 Dos命令: set classpath = path1; path2 [;…] path 为包的存放路径,注意: path 中应包含当前路径 . 如: set classpath = .;d:\java;e:\ppp\xxx

这样的话,编译使用包的 .java文件时就无需带 classpath参数。 javac PackageDemo.java

执行 Java.exe –cp . PackageDemo

Page 35: 第 4 章   编写类

包的总结

• 创建包package mypackage;

• 访问 Java 包成员 mypackage.My_Class

• 导入包• import package_name.*;

• 导入子包 import package_name.*;

Page 36: 第 4 章   编写类

AWT 概述

创建 GUI创建 GUI通过

java.awt 包

容器

组件

布局管理器

字体

事件

图形和绘制方法

包含 AWT 容器组件

以图形表示的对象允许用户交互

创建并构造用于选择新字体的对象

用于用户和系统交互

AW

T

包含内容 使用 AWT 图形方法相对于窗口绘制图形

定义 GUI 组件的位置

AWT( 重量级组件)

AWT( 重量级组件)

Page 37: 第 4 章   编写类

Swing

创建 GUI创建 GUI通过

Javax.swing 包

Sw

ing

包含内容

容器

组件

可改变的外观

Java2D图形绘制

包含 Swing 组件

以图形表示的对象允许用户交互

使用 Java2D绘制图形

可更换图形界面的风格

Swing(轻量级组件,纯 Java 组件)

Swing(轻量级组件,纯 Java 组件)

Page 38: 第 4 章   编写类

轻量级组件

可改变的外观

MVC 结构

性能更稳定

优点

Swing

Swing (与 AWT 相比)

Swing (与 AWT 相比)

Page 39: 第 4 章   编写类

Swing 容器组件

主窗口

Swing 应用程序

创建容器

设置容器大小(对框架及面板而言)

设置容器可见度(对框架及面板而言)

创建顶层容器

顶层容器(每个应用程序中至少有一个)

内容面板

主要显示区域包含 GUI 中的可视组件

Page 40: 第 4 章   编写类

javax.swing 包

javax.swing 包

常见容器

JFrame JFrame JScrollPane JScrollPane JPanel JPanel

1. 扩展 java.awt.Frame 类2. 用于在 Swing 程序中创建窗口

3. 包含边框、标题和用于关闭和图标化窗口的按钮

1. 中间容器2. 用于将较小的轻量级组件

组合在一起3. 与内容窗格相似,面板在默认情况下不透明

1. 管理视区、滚动条及可选的行和列的标题视区

Swing 容器组件

Page 41: 第 4 章   编写类

javax.swing 包

javax.swing 包

1. 扩展 java.awt.Frame 类2. 用于在 Swing 程序中创建窗口

3. 包含边框、标题和用于关闭和图标化窗口的按钮

常用的顶层容器

JFrame JFrame JScrollPane JScrollPane JPanel JPanel

1. 中间容器2. 用于将较小的轻量级组件组合

在一起3. 与内容窗格相似,面板在默认

情况下不透明

1.管理视区、滚动条及可选的行和列的标题视区

Swing 容器组件

JFrame 类的方法JFrame()

JFrame(String title)

void pack()

void setSize(int width, int height)

Dimension getSize()

void setTitle(String name)

JPanel 类的方法JPanel()

JPanel(LayoutManager layout)

void add(Component comp)

Void setLayout(LayoutManager layout)

JScrollPane 类的方法 JScrollPane()

JScrollPane(Component view)

void setVerticalScrollBarPolicy(int const)

void setHorizontalScrollBarPolicy(int const)

Page 42: 第 4 章   编写类

Swing GUI 组件JTexField

JComboBox

JCheckBox

JButtonJRadioButton

JLabel

JTexArea

Page 43: 第 4 章   编写类

组件和容器GUI 组件( component )是一个对象,代表一个用于显示信息或允许用户以某种方式与程序进行交互的屏幕元素。

容器( container )是一个保存和组织其他组件的特殊组件,框架和面板就是两种容器 

关键概念 : 容器是一个保存和组织其他组件的特殊 GUI 组件。

Page 44: 第 4 章   编写类

JLabel

Properties Description

1. A label is not

interactive and does not respond to any input events

1. Displays a label on form

2. In Swing, labels can display text as well as images

JLabel方法 说明JLabel() JLabel() 创建一个默认的 JLabel 实例JLabel(String text) 以指定的文本创建 JLabel 实例JLabel(Icon image) 以指定的图像创建 JLabel 实例

getText() 返回标签显示的文本字符串setIcon(Icon icon) 定义标签将显示的内容setText(String text) 定义此组件将要显示的单行文本

Page 45: 第 4 章   编写类

JTextField

Properties Description

1. JTextField component allows entering/editing a single line of

text.

1. JTextField is a lightweight component that allows the editing of a single line of text

JTextField

方法 说明JTextField() 构造一个新的文本输入框JTextField(String text) 构造一个新的文本输入框 ,以指定文本

作为初始文本

getColumns() 返回文本字段中的列数

setColumns(int columns) 设置文本字段中的列数,然后使布局无效

setHorizontalAlignment(int value)

设置文本字段中文本的水平对齐方式: JTextField. LEFTJTextField.CENTER JTextField.RIGHT

Page 46: 第 4 章   编写类

JTextArea

属性 说明JTextArea 组件接受用户输入的多行文本

JTextArea 允许用户编辑已输入的文本

JTextArea

说明 描述JTextArea() 构造一个新的文本区 JTextArea(String text)

用指定的显示文本构造一个新的文本区

setFont(Font f) 设置文本区的字体getText() 获取文本区中的文本字符串

Page 47: 第 4 章   编写类

JButton

属性 说明JButton 类派生自 javax.swing.AbstractButton 类,该类由 JComponent 扩展而来

JButton 对象包含一个文本标签、图像图标或两者,描述按钮、文本 /图标周围的空白区域和边框的用途

方法 说明JButton( ) 创建不带文本和图标的按钮

JButton(Icon icon) 创建带图标的按钮

JButton(String text) 创建带文本的按钮

JButton(String text, Icon icon)

创建带文本和图标的按钮

setRolloverIcon(Icon img) 当鼠标经过时,显示指定的图标

setSelectedIcon(Icon img) 当选择按钮时,显示 img 指定的图标

Page 48: 第 4 章   编写类

框架和面板框架 (frame) 是一个容器,用户显示基于 GUI 的 Java应用程序界面。

面板( panel )也是一个容器,面板自身不能独立显示。 

关键概念 : 框架作为一个独立窗口显示,而面板则只能作为其他容器的组成部分显示。

Page 49: 第 4 章   编写类

布局管理器用户界面上的屏幕组件可以按照一定的格式布局 例如水平排列,或按网格方式排列布局管理器类是一组类,它

实现 java.AWT.LayoutManager 接口 帮助在容器中放置组件

Java 中可用的各种布局如下: BorderLayout FlowLayout GridLayout

Page 50: 第 4 章   编写类

BorderLayout

上边的组件

下边的组件

容器容器

North

South

EastWest CENTER

Page 51: 第 4 章   编写类

West East

BorderLayout

上边的组件

下边的组件

容器容器

North

South

Center

方法 说明BorderLayout( ) 创建新的 BorderLayout,组件之间没有间距

setHgap(int hgap) 将组件间的水平间距设置为指定的值

setVgap(int vgap) 将组件间的垂直间距设置为指定的值

Page 52: 第 4 章   编写类

FlowLayout

容器容器

流布局是面板的默认布局管理器左上角

右下角

依次排序的组件

垂直或水平间距

Page 53: 第 4 章   编写类

FlowLayout

容器容器

流布局是面板的默认布局管理器左上角

右下角

顺序排列的组件

垂直或水平间距

方法 说明FlowLayout( ) 构造新的中间对齐的 FlowLayout,

将垂直和水平间距保留为 5 个像素

setAlignment( int align) 设置指定布局的对齐方式setHgap(int hgap) 设置指定布局的水平间距setVgap(int vgap) 设置指定布局的垂直间距

Page 54: 第 4 章   编写类

GridLayout

行行

列列

组件大小相同

重新调整组件大小以适合各自的单元

指定网格中的行数和列数,创建网格布局

Page 55: 第 4 章   编写类

GridLayout

行行

列列

组件大小相同

重新调整组件大小以适合各自的单元

指定网格中的行数和列数,创建网格布局

方法 描述GridLayout( ) 创建网格布局,默认为每个组件占用一整列

和一单行GridLayout(int rows, int cols)

用指定的行数和列数创建网格布局。

GridLayout(int rows, int cols, int hgap, int vgap)

用指定的行数和列数、指定的水平和垂直间距创建网格布局

setColumns(int cols) 将相应布局中的列数设置为指定值setHgap(int hgap) 将相应布局中的水平间距设置为指定值setVgap(int vgap) 将相应布局中的垂直间距设置为指定值setRows(int rows ) 将相应布局中的行数设置为指定值