Version 3.0
第四章类的高级特性
2
回顾
类是对象的抽象,将对象的属性和行为 抽象为类中的数据和方法。
extends 关键字用于继承类。
super关键字用来解决如何直接访问或初始化从父类继承来的属性 。
构造函数名称与类的名称相同,且没有返回类型。
方法重载和方法覆盖是 Java实现多态性机制的方式。
3
目标
掌握类的静态成员
掌握 final关键字用法
掌握抽象类的定义和用法
掌握接口的定义和用法
掌握高级访问控制
了解内部类的概念
4
类的静态成员
类中的静态变量、方法或代码块属于类,而不属于某个特定的对象。
类的静态成员可以与类的名称一起使用,而无需创建类的对象。
静态变量或方法也称为类的变量或方法。
用 static修饰符修饰,
可以是变量、方法或代 码块
5
静态变量
不管创建了类的多少实例,整个类中静态变量的副本只有一个。
引用静态变量的方法:
- 通过引用类的任一实例
- 通过类的名称
class StaticDemo {
static int x = 0;
StaticDemo(){x++;}
}
StaticDemo d1 = new StaticDemo();
StaticDemo d2 = new StaticDemo();
d1.x = 100 ;
d2.x = 200;
testVariable = d1.x;
通过类实例访问不是一个好方法
StaticDemo d1 = new StaticDemo();
StaticDemo d2 = new StaticDemo();
StaticDemo.x = 100;
StaticDemo.x = 200;
testVariable = StaticDemo.x;
声明为 static的变量实质上就是全局变量通过类名访问
6
静态方法
与静态方法相关的几个要点:
– 类的静态方法只能访问其他的静态成员
– 静态方法没有 this
– 静态方法不能被覆盖为非静态方法
class StaticFun {
static int i = 10;
int j;
static void setValue(int x) {
j=x;//出错
System.out.println(" "+ i);
}
} 不能访问非静态变量 j,可以访问静态变量 i
class StaticTest {
static void test() { }
}
class Staticex extends StaticTest{
void test() {}//出错
}
7
静态块
如果需要通过计算来初始化静态变量,可以声明一个静态块。
静态块仅在该类被加载时执行一次。
只能初始化类的静态数据成员。
class TryInitialization {
static int[] values = new int[10]; //静态数组成员
static {
for(int i=0; i<values.length; i++)
values[i] = (int)(100.0*Math.random());
}
}
8
final 关键字 /final类
final 修饰符可应用于类、方法和变量。
final在应用于类、方法和变量时意义是不同的,但本质是一样的,final表示不可改变。
声明为 final的类不能被继承。
final 类示例:
java.lang.String
final class TestFinal {
int i = 7;
int j = 1;
void f() {}
}
class Further extends TestFinal {}
final类不能被继承
9
final 方法
在方法声明中使用 final 关 键字向编译器表明子类不能覆盖此方法 。
在声明类中,一个 final 方法只被实现一次。
如果一个类为 final 类,那么它的所有方法都为隐式的 final 方法 。
class TestFinal {
final void f() {}
}
class Further extends TestFinal {
final void f(){}
} final方法不能被覆盖
10
final 变量
一个变量可以声明为 final,这样做的目的是阻止它的内容被修改。
声明 final变量后,只能被初始化一次,然后就不能对其值进行修改 。
一个 final变量实质上是一个常量。
class FinalDemo {
public static void main(String args[]){
final int noChange = 20;
noChange = 30;
}
} final变量不能被修改
11
抽象类 2-1
定义抽象类的目的是提供可由其子类共享的一般形式。
子类可以根据自身需要扩展抽象类。
抽象类不能实例化。
抽象方法没有函数体。
抽象方法必须在子类中给出具体实现。
abstract 修饰符可与类和方法一起使用
12
抽象类 2-2
在以下情况下,某个类将成为抽象类:
– 当一个类的一个或多个方法为抽象方法时。
– 当该类为一个抽象类的子类,并且没有为所有抽象方法提供实现细节或方法主体时。
– 当一个类实现一个接口,并且没有为所有抽象方法提供实现细节或方法主体时。
13
抽象类示例
abstract class Employee {
int basic = 2000;
abstract void salary();//抽象方法
}
class Manager extends Employee{
void salary() {
System.out.println("薪资等于 "+basic*5);
}
}
class Worker extends Employee {
void salary() {
System.out.println("薪资等于 "+basic*2);
}
}
抽象方法没有 方法主体在子类中提供 实现在子类中提供 实现
14
接口
一个接口允许一个类从几个接口继承而来。
Java 程序一次只能继承一个类但可以实现几个接口。
接口不能有任何具体的方法。
接口也可用来定义可由类使用的一组常量。
接口提供,is a”关系。
15
创建接口的步骤 2-1
// 有方法的接口
public interface myinterface {
public void add(int x,int y);
public void volume(int x,int y,int z);
}
// 定义程序使用的常量的接口
public interface myconstants {
public static final double price = 1450.00;
public static final int counter = 5;
}
定义一个接口:
16
创建接口的步骤 2-2
编译如下:
javac myinterface.java
用关键字 implements 实现接口,例如:
class demo implements myinterface
如果有一个以上接口被实现,则用逗号隔开接口名称,如下所示:
class demo implements Mycalc,Mycount
17
接口使用示例
interface A {
double g=9.8;
void show( );
}
class InterfaceTest {
public static void main(String args[ ]){
B b=new B( );
b.show( );
}
}
class B implements A {
public void show( ) {
System.out.println(“g=“+g);
}
}
18
高级访问控制
访问修饰符为:
- public
- protected
- private
如果一个类或类的成员前没有任何访问修饰符时,它们获得缺省的访问权限。
19
public 访问修饰符
只有在使用 public 访问修饰符时,类的成员才可被同一包或不同包中的所有类访问。
也就是说,public 访问修饰符可以使类的特性公用于任何类。
20
缺省访问权限 /protected 访问修饰符
缺省的成员可以被同一包中的其他类访问。
protected 访问修饰符允许类本身、同一包中的所有类和不同包中的子类访问 。
如果希望一个成员在当前包外可见,但仅仅是成员所在类的子类直接可见,就要使用 protected 修饰该成员。
21
private 访问修饰符
private 访问修饰符是限制性最大的一种访问修饰符。
被声明为 private的成员只能被此类中的其他成员访问,不能被类外看到。
继承体系结构中最高级别的类决不会被声明为 private 类。
22
高级访问控制总结访问控制 private成员 缺省的成员 protected成员 public成员同一类中成员
同一包中其他类 ×
不同包中子类 × ×
不同包中非子类 × × ×?
23
封装类 基本数据类型不是对象层次结构的组成部分。有时需要象处理对象一样处理这些基本数据类型,可通过相应的
,封装类,来将其,封装,。
数据类型 封装类
boolean Boolean
byte Byte
char Character
double Double
float Float
int Int
long Long
short Short
24
封装类使用示例
Boolean wrapBool = new Boolean("false");
Integer num1 = new Integer ("31");
Integer num2 = new Integer("3");
int sum = num1.intValue() * num2.intValue();
intValue()
返回调用对象的整型值
class CmdArg {
public static void main(String args[]){
int sum = 0;
for(int cnt = 0; cnt < args.length; cnt++)
sum+=Integer.parseInt(args[cnt]);
System.out.println("和为,"+sum);
}
} parseInt()方法将执行从字符串转换成与之相应的整型( int) 值
25
内部类
内部类为非静态的嵌套类。
在类中定义的类称为内部类。
内部类之外的类称为外部类。
内部类可以访问其外部类的所有变量和方法,并能够以和外部类的其他非静态成员相同的方式直接引用它们。
内部类完全在其包围类的范围之内。
26
总结 2-1
类中的静态变量、方法或代码块并不具体到实例,它们可以与类的名称一起使用,
而无需创建类的对象来访问类的静态特性。
final 修饰符可应用于类、方法和变量。
定义抽象类的目的是提供可由其子类共享的一般形式。
接口就是需要由其他类实现的行为模板。
27
总结 2-2
访问修饰符为:
- public
- protected
- private
封装类就是封装基本数据类型的类 。
内部类指嵌入外部类内的类,在类中定义的类称为内部类。