有时候,可能希望阻止人们利用某个类定义子类。不允许扩展的类被称为 final 类。
public final class Executive extends Manager
{
.....
}
final 类中的所有方法自动地成为 final 方法
不过, 如果将一个类声明为 final, 只有其中的方法自动地成为 final,而不包括域
因此,应该养成这样一个良好的程序
设计习惯: 在进行类型转换之前, 先查看一下是否能够成功地转换。这个过程简单地使用
instanceof 操作符就可以实现。 例如:
if (staff[1] instanceof Manager)
{
boss = (Manager) staff[1]:
}
instanceof:将超类转换为子类时使用!
Abstract
为了提高程序的清晰度, 包含一个或多个抽象方法的类本身必须被声明为抽象的。
除了抽象方法之外,抽象类还可以包含具体数据和具体方法。
抽象类不能被实例化。也就是说, 如果将一个类声明为 abstract, 就不能创建这个类的对
象。 例如,表达式
new Person("Vi nee Vu")
是错误的, 但可以创建一个具体子类的对象。
需要注意, 可以定义一个抽象类的对象变量, 但是它只能引用非抽象子类的对象。 例如,
Person p = new Student("Vinee Vu" , "Economics") ;
这里的 p 是一个抽象类 Person 的变量, Person 引用了一个非抽象子类 Student 的实例。
例子:在超类中不定义getDescription()方法,只将其设为abstract类,为何不直接在子类中实现getDescription()方法呢?
因为若只在子类中实现方法,不在超类中声明方法,则该方法在超类进行对象化时不能调用
Person[] people = new Person[2];
people[0] = new Enp1oyee(. . .) ;
people[1] = new Student(. . .) ;
若只在Employee和Student中实现getDescription()方法,则people对象不能调用!因此需要在超类中将其设为abstract类,
将某个方法设为abstract时,就不用在类中实现其方法,只要说明该方法即可。
例:实现其方法:
public String getDescriptionO
{
return "";
}
说明该方法:
public abstract String getDescription();
书写更加简便明了!
下面归纳一下 Java 用于控制可见性的 4 个访问修饰符:
1 ) 仅对本类可见 private。
2 ) 对所有类可见 public:
3 ) 对本包和所有子类可见 protected。
4 ) 对本包可见—默认(很遗憾,) 不需要修饰符。
equals()与instance of的不同之处:
此时的两个不同方法是针对与对象来说
主要区别在于使用instance of 来比较两个对象是否相等时不能判断对象A是否对象B的子类的情况
equals()具有以下特性:
1 ) 自反性: 对于任何非空引用 x, x.equals(?0 应该返回 truec
2 ) 对称性: 对于任何引用 x 和 y, 当且仅当 y.equals(x) 返回 true, x.equals(y) 也应该返
回 true。
3 ) 传递性: 对于任何引用 x、 y 和 z, 如果 x.equals(y) 返 N true, y.equals(z) 返回 true,
x.equals(z) 也应该返回 true。
4 ) 一致性: 如果 x 和 y 引用的对象没有发生变化,反复调用 x.eqimIS(y) 应该返回同样
的结果。
5 ) 对于任意非空引用 x, x.equals(null) 应该返回 false,
检测 this 与 otherObject 是否引用同一个对象:
if (this = otherObject) return true;
比较 this 与 otherObject 是否属于同一个类。如果 equals 的语义在每个子类中有所改
变,就使用 getClass 检测:
if (getClass() != otherObject.getCIassO) return false;
如果所有的子类都拥有统一的语义,就使用 instanceof 检测:
if (!(otherObject instanceof ClassName)) return false;
由于 hashCode 方法定义在 Object 类中, 因此每个对象都有一个默认的散列码,其值为对象的存储地址。
方法参数变量可变的方法:
例:printf方法的定义:
public class PrintStream
{
public PrintStream printf(String fmt , Object... args) { return format(fmt, args); }
}
Object... args 表示参数变量可以多个!
自己定义创建方法:
public static double max(double... values)
{
double largest = Double.NECATIVEJNFINITY;
for (double v : values) if (v > largest) largest = v;
return largest;
}
枚举类:
public enuni Size { SMALL, MEDIUM, LARGE, EXTRAJARGE };
在比较两个枚举类型的值时, 永远不需要调用 equals, 而直接使用“ = =” 就可以了。
接口:
要知道接口不能提供哪些功能?
接口绝不能含有实例域, 在 JavaSE 8 之前, 也不能在接口中实现方法。
可以将接口看成是没有实例域的抽象类
例子:
首先定义一个interface接口:
public interface Comparabs {
int compareTo(Employee employee);
}
然后定义一个类来implements这个接口:
public class Employee implements Comparabs {
public static void main(String[] args) {
}
@Override
public int compareTo(Employee employee) {
return 0;
}
}
类中必须override在接口中定义的方法!
如同使用 instanceof检查一个对象是否属于某个特定类一样, 也可以使用instanceof 检查一个对象是否实现了某个特定的接口:
if (anObject instanceof Comparable) { . . . }
在接口中不能包含实例域或静态方法,但却可以包含常量。例如:
public interface Powered extends Moveable
{
double milesPerCallonO;
double SPEED_LIHIT = 95; // a public static final constant
}
与接口中的方法都自动地被设置为 public—样, 接口中的域将被自动设为 public static final
static 表示多个对象共享一个域!
final表示在初次定义后域不可改变!
继承与接口的区别主要在于JAVA不支持多继承,而支持多接口
若是只继承单个接口,便可用继承代替。
例:
抽象类:
abstract class Comparable // why not?
{
public abstract int compareTo(Object other);
}
继承类:
class Employee extends Comparable // why not?
{
public int compareTo(Object other) { . . . }
}
问题在于:
class Employee extends Person, Comparable // Error
class Employee extends Person implements Comparable // OK
若实现的多个接口出现了相同的方法,从而导致冲突,则按照以下原则进行处理:
- 超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
- 接口冲突。 如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型 (不论是否是默认参数)相同的方法, 必须覆盖这个方法来解决冲突。
当方法实现冲突时,JAVA不会从两个相同或者类似的方法中选择其中一个,而是让程序员来解决这个二义性。程序员需要在当前冲突的类中重新实现发生冲突的方法!
若是类与接口发生了冲突,则遵循"类优先”的原则!接口中的冲突方法将会被自动忽略!

2526

被折叠的 条评论
为什么被折叠?



