java基础之 Advanced Class Design

 java基础之 Advanced Class Design

Abstract Classes

In many programming situations, you want to specify an abstraction without specifying

implementation-level details. In such cases, you can use either abstract classes or interfaces. Abstract classes

are used when you want to define an abstraction with some common functionality.

Points to Remember

Review the following points about abstract classes and abstract methods :

? The abstract keyword can be applied to a class or a non-static method.

? An abstract class may have methods or fields declared static. However, the abstract

keyword cannot be applied to fields or static methods.

? An abstract class can extend another abstract class or can implement an interface.

? An abstract class can be derived from a concrete class! Although the language allows

it, it is not a good idea to do so.

? An abstract class need not declare an abstract method, which means it is not

necessary for an abstract class to have any methods declared as abstract. However, if

a class has an abstract method, it should be declared as an abstract class.

? A subclass of an abstract class needs to provide implementation of all the abstract

methods; otherwise you need to declare that subclass as an abstract class.

Using the “final” Keyword

The final keyword can be applied for classes, methods, and variables. You cannot extend a final class,

you cannot override a final method, and you cannot change the value of a final variable once it is initialized.

Final Classes

A final class is a non-inheritable class—that is to say, if you declare a class as final, you cannot subclass it.

Two important reasons you may not want to allow a class to be subclassed are:

1. To prevent a behavior change by subclassing. In some cases, you may think that

the implementation of the class is complete and should not change. If overriding

is allowed, then the behavior of methods might be changed. You know that a

derived object can be used where a base class object is required, and you may

not prefer it in some cases. By making a class final, the users of the class are

assured the unchanged behavior.

2. Improved performance. All method calls of a final class can be resolved at

compile time itself. As there is no possibility of overriding the methods, it is not

necessary to resolve the actual call at runtime for final classes, which translates to

improved performance. For the same reason, final classes encourage the inlining

of methods. With inlining, a method body can be expanded as part of the calling

code itself, thereby avoiding the overhead of making a function call. If the calls

are to be resolved at runtime, they cannot be inlined.

In the Java library, many classes are declared as final; for example, the String (java.lang.String)

and System (java.lang.System) classes. These classes are used extensively in Java programs. If these

two classes are not declared final, it is possible for someone to change the behavior of these classes by

subclassing and then the whole program can start behaving differently. To avoid such a problem, widely

used classes like these and wrapper classes such as Number and Integer are made final in the Java library.

Final Methods and Variables

In a class, you may declare a method final. The final method cannot be overridden. Therefore, if you have

declared a method as final in a non-final class, then you can extend the class but you cannot override the

final method. However, other non-final methods in the base class can be overridden in the derived class

implementation.

Final variables are like CD-ROMs: once you write something on them, you cannot write again. In

programming, constants such as PI can be declared as final since you don’t want anyone to modify their

values. If you try to change a final variable after initialization, you will get a compiler error.

Points to Remember

Review the following points :

? The final modifier can be applied to a class, method, or variable. All methods of a

final class are implicitly final (hence non-overridable).

? A final variable can be assigned only once. If a variable declaration defines a

variable as final but did not initialize it, then it is referred to as blank final. You need

to initialize a blank final in all the constructors you have defined in the class or in an

initialization block.

? The keyword final can be applied to parameters. The value of a final parameter

cannot be changed once assigned.

Flavors of Nested Classes

Create inner classes including static inner class, local class, nested class, and anonymous inner class

Classes defined within the body of another class (or interface) are known as nested classes. Typically

you define a class, which is a top-level class directly belonging to a package. In contrast, nested classes are

classes contained within another class or interface.

What is the benefit of creating classes inside another class or interface? There are several benefits. First,

you can put related classes together as a single logical group. Second, nested classes can access all class

members of the enclosing class, which might be useful in certain cases. Third, nested classes simplify code.

For example, anonymous inner classes are useful for writing simpler event-handling code with AWT/Swing.

There are four types or flavors of nested classes in Java:

? Static nested class

? Inner class

? Local inner class

? Anonymous inner class

The distinctions among these four flavors are not evident at first sight. Figure 3-1 helps clarify the

differences between them. A local class is defined within a code block (whether a method, constructor, or

initialization block), whereas a non-local class is defined inside a class. A static class is qualified using the

static keyword, whereas a non-static class does not use the static keyword with the class definition. In an

anonymous class, you don’t provide the name of the class; you just define its body.

As you can observe in Figure 3-1, static nested classes are static and non-local, whereas inner classes

are non-static and non-local. A non-static and local nested class is a local inner class, and a local and

anonymous nested class is an anonymous inner class.

Static Nested Classes (or Interfaces)

You can define a class (or an interface) as a static member inside another class (or interface). Since the

outer type can be a class or an interface and the inner ones can also be a class or interface, there are four

combinations. The following are examples of these four types so that you can see their syntax:

class Outer { // an outer class has a static nested class

static class Inner {}

}

interface Outer { // an outer interface has a static nested class

static class Inner {}

}

class Outer { // an outer class has a static nested interface

static interface Inner {}

}

interface Outer { // an outer interface has a static nested interface

static interface Inner {}

}

You don’t have to explicitly use the static keyword with a nested interface, since it is implicitly static.

Now, let’s look at an example that creates and uses static nested classes.

Points to Remember

Here are some notable aspects of static nested classes (and interfaces) that will help you on the OCPJP 8 exam:

? The accessibility (public, protected, etc.) of the static nested class is defined by

the outer class.

? The name of the static nested class is expressed with

OuterClassName.NestedClassName syntax.

? When you define an inner nested class (or interface) inside an interface, the nested

class is declared implicitly public and static. This point is easy to remember: any

field in an interface is implicitly declared public and static, and static nested

classes have this same behavior.

? Static nested classes can be declared abstract or final.

? Static nested classes can extend another class or they can be used as base classes.

? Static nested classes can have static members. (As you’ll see shortly, this statement

does not apply to other kinds of nested classes.)

? Static nested classes can access the members of the outer class (only static members,

obviously).

? The outer class can also access the members (even private members) of the nested

class through an object of a nested class. If you don’t declare an instance of the

nested class, the outer class cannot access nested class elements directly.

Inner Classes

You can define a class (or an interface) as a non-static member inside another class. How about declaring a

class or an interface inside an interface? As you just saw in the third bullet above about static inner classes,

when you define a class or an interface inside an interface, it is implicitly static. So, it is not possible to

declare a non-static inner interface! That leaves two possibilities:

class Outer { // an outer class has an inner class

class Inner {}

}

class Outer { // an outer class has an inner interface

interface Inner {}

}

Every inner class is associated with an instance of the outer class. in other words, an inner class is always

associated with an enclosing object.

The outer and inner classes share a special relationship, like friends or members of same family.

Member accesses are valid irrespective of the access specifiers such as private. However, there is subtle

difference. You can access members of an outer class within an inner class without creating an instance; but

this is not the case with an outer class. You need to create an instance of inner class in order to access the

members (any members, including private members) of the inner class.

One limitation of inner classes is that you cannot declare static members in an inner class, like this:

class Outer {

class Inner {

static int i = 10;

}

}

If you try to do so, you’ll get the following compiler error:

Outer.java:3: inner classes cannot have static declarations

static int i = 10;

Points to Remember

Here are some important rules about inner classes and interfaces that might prove useful in the OCPJP 8 exam:

? The accessibility (public, protected, etc.) of the inner class is defined by the

outer class.

? Just like top-level classes, an inner class can extend a class or can implement

interfaces. Similarly, other classes can extend an inner class, and other classes or

interfaces can extend or implement an inner interface.

? An inner class can be declared final or abstract.

? Inner classes can have inner classes, but you’ll have a hard time reading or

understanding such complex nesting of classes. (Meaning: Avoid them!)

Local Inner Classes

A local inner class is defined in a code block (say, in a method, constructor, or initialization block). Unlike

static nested classes and inner classes, local inner classes are not members of an outer class; they are just

local to the method or code in which they are defined.

Here is an example of the general syntax of a local class:

class SomeClass {

void someFunction() {

class Local { }

}

}

As you can see in this code, Local is a class defined within someFunction. It is not available outside of

someFunction, not even to the members of the SomeClass. Since you cannot declare a local variable static,

you also cannot declare a local class static.

Since you cannot define methods in interfaces, you cannot have local classes or interfaces inside an

interface. Nor can you create local interfaces. In other words, you cannot define interfaces inside methods,

constructors, and initialization blocks.

You can pass only final variables to a local inner class. if you don‘t declare a variable that a local inner

class accesses, the compiler will treat it as effectively final.

Points to Remember

The following points about local classes may come up in the OCPJP 8 exam:

? You can create a non-static local class inside a body of code. Interfaces cannot have

local classes, and you cannot create local interfaces.

? Local classes are accessible only from the body of the code in which the class is

defined. The local classes are completely inaccessible outside the body of the code in

which the class is defined.

? You can extend a class or implement interfaces while defining a local class.

? A local class can access all the variables available in the body of the code in which it

is defined. Variables accessed by local inner classes are considered effectively final.

Anonymous Inner Classes

As the name implies, an anonymous inner class does not have a name. The declaration of the class automatically

derives from the instance-creation expression. They are also referred to simply as anonymous classes.

An anonymous class is useful in almost all situations where you can use a local inner class. A local

inner class has a name, whereas an anonymous inner class does not—and that’s the main difference. An

additional difference is that an anonymous inner class cannot have any explicit constructors. A constructor

is named after the name of the class, and since an anonymous class has no name, it follows that you cannot

define a constructor!

(A note here before we proceed: there are no such things as “anonymous interfaces.”)

Here is an example to understand the syntax of a local class:

class SomeClass {

void someFunction() {

new Object() { };

}

}

This code looks cryptic, doesn’t it? What is going on here? In the statement new Object() { };, you are

declaring a derived class of Object directly using the new keyword. It doesn’t define any code and returns an

instance of that derived object. The created object is not used anywhere, so it is ignored. The new expression

invokes the default constructor here; you could choose to invoke a multiple argument constructor of the

base class by passing arguments in the new expression.

Points to Remember

Note these points about anonymous classes that may be useful for the OPCJP 8 exam:

? Anonymous classes are defined in the new expression itself.

? You cannot explicitly extend a class or explicitly implement interfaces when defining

an anonymous class.

Enum Data Type

Use enumerated types including methods, and constructors in an enum type

Points to Remember

? Enums are implicitly declared public, static, and final, which means you cannot

extend them.

? When you define an enumeration, it implicitly inherits from java.lang.Enum.

Internally, enumerations are converted to classes. Further, enumeration constants

are instances of the enumeration class for which the constant is declared as a

member.

? You can apply the valueOf() and name() methods to the enum element to return the

name of the enum element.

? If you declare an enum within a class, then it is by default static.

? You cannot use the new operator on enum data types, even inside the enum class.

? You can compare two enumerations for equality using == operator.

? If enumeration constants are from two different enumerations, the equals() method

does not return true.

? When an enumeration constant’s toString() method is invoked, it prints the name

of the enumeration constant.

? The static values() method in the Enum class returns an array of the enumeration

constants when called on an enumeration type.

? Enumeration constants cannot be cloned. An attempt to do so will result in a

CloneNotSupportedException.

Enum avoids magic numbers, which improves readability and understandability of the source code. also,

enums are typesafe constructs. therefore, use enums wherever you need a set of related constants.

Interfaces

Develop code that declares, implements, and/or extends interfaces and use the atOverride annotation

An interface is a set of abstract methods that defines a protocol (i.e., a contract for conduct). Classes

that implement an interface must implement the methods specified in the interface. An interface defines a

protocol, and a class implementing the interface honors the protocol. In other words, an interface promises

certain functionality to its clients by defining an abstraction. All the classes implementing the interface

provide their own implementations for the promised functionality.

Points to Remember

Here are some key points about interfaces that will help you in the OCPJP 8 exam:

? An interface cannot be instantiated. A reference to an interface can refer to an object

of any of its derived types implementing it.

? An interface can extend another interface. Use the extends (and not the implements)

keyword for extending another interface.

? Interfaces cannot contain instance variables. If you declare a data member in an

interface, it should be initialized, and all such data members are implicitly treated as

“public static final” members.

? An interface can have three kinds of methods: abstract methods, default methods,

and static methods.

? An interface can be declared with empty body (i.e., an interface without any

members). For example, java.util defines the interface EventListener

without a body.

? An interface can be declared within another interface or class; such interfaces are

known as nested interfaces.

? Unlike top-level interfaces that can have only public or default access, a nested

interface can be declared public, protected, or private.

? If you are implementing an interface in an abstract class, the abstract class does not

need to define the method. But, ultimately a concrete class has to define the abstract

method declared in the interface.

? You can use the @Override annotation for a method to indicate that it is overriding a

method from its base type(s).

Points to Remember

Here are some key points about abstract, default, and static methods that will help you in the OCPJP 8 exam:

? You cannot declare members as protected or private. Only public access is

allowed for members of an interface. Since all methods are public by default, you can

omit the public keyword.

? All methods declared in an interface (i.e., without a method body) are implicitly

considered to be abstract. If you want, you can explicitly use the abstract qualifier

for the method.

? Default methods must have a method body. Default methods must be qualified

using the default keyword. The classes implementing the interface inherit the

default method definitions and they can be overridden.

? A default method can be overridden in a derived class as an abstract method; for

such overriding, the @Override annotation can also be used.

? You cannot qualify default methods as synchronized or final.

? Static methods must have a method body and they are qualified using the static

keyword.

? You cannot provide abstract keyword for static methods: Remember that you

cannot override static methods in derived classes, so it’s conceptually not possible to

leave static methods abstract by not providing a method body.

? You cannot use default keyword for static methods because all default methods are

instance methods.

Lambda Functions

introduction of lambdas required coordinated changes in the language, library, and the vM

implementation:

? the arrow operator (“->”) for defining lambda functions, the double colon operator

(“::”) used for method references, and the default keyword

? the streams library and the integration of the collections library with streams

? lambda functions are implemented using the invokedynamic instruction introduced

in Java 7

to support introduction of lambdas into the language, the type inference has also been strengthened in

Java 8. lambdas enabled library writers to create parallel algorithms in the library to exploit inherent

parallelism in the modern hardware (i.e., multi cores).

Lambda Functions: Syntax

A lambda function consistss of optional parameters, the arrow token, and the body:

LambdaParameters -> LambdaBody

? LambdaParameters are parameters to the lambda function are passed within opening

parenthesis “(“ and closing parenthesis ”)”. When more than one parameter is

passed, they are separated by commas.

? The arrow operator. To support lambdas, Java has introduced a new operator “->”,

also known as lambda operator or arrow operator. This arrow operator is required

because we need to syntactically separate the parameter from the body.

? LambdaBody can be an expression or a block. The body could consist of single

statement (in that case no explicit curly braces defining a block are required); such

a lambda body is known as "expression lambda." If there are many statements in a

lambda body, they need to be in a block of code; such a lambda body is known as

“block lambda.”

Compiler performs type inference for lambda expressions:

? The compiler infers the type of the parameters if you do not specify the type

parameters in a lambda function definition. When you specify the type of

parameters, you need to specify all or none; or else you will get a compiler error.

? You can omit the parenthesis if there is only one parameter. But in this case, you

cannot provide the type explicitly. You should leave it to the compiler to infer the

type of that single parameter.

? The return type of the lambda function is inferred from the body. If any of the code in

the lambda returns a value, then all the paths should return a value; or else you will

get a compiler error.

Some examples of valid lambda expressions (assuming that relevant functional interfaces are available):

? (int x) -> x + x

? x -> x % x

? () -> 7

? (int arg1, int arg2) -> (arg1 + arg2) / (arg1 – arg2)

Effectively Final Variables

Lambda functions can refer to local variables from the enclosing scope. The variable needs to be explicitly

declared final or that variable will be treated as effectively final. Effectively final means that the compiler treats

the variable as a final variable and will issue an error if we try to modify it within the lambda function or in the

rest of the function. This behavior of lambdas is similar to accessing variables in outer scope from local and

anonymous classes. The variables they access are also considered effectively final。nctions

Create and use Lambda expressions

introduction of lambdas required coordinated changes in the language, library, and the vM

implementation:

? the arrow operator (“->”) for defining lambda functions, the double colon operator

(“::”) used for method references, and the default keyword

? the streams library and the integration of the collections library with streams

? lambda functions are implemented using the invokedynamic instruction introduced

in Java 7

to support introduction of lambdas into the language, the type inference has also been strengthened in

Java 8. lambdas enabled library writers to create parallel algorithms in the library to exploit inherent

parallelism in the modern hardware (i.e., multi cores).

Lambda Functions: Syntax

A lambda function consistss of optional parameters, the arrow token, and the body:

LambdaParameters -> LambdaBody

? LambdaParameters are parameters to the lambda function are passed within opening

parenthesis “(“ and closing parenthesis ”)”. When more than one parameter is

passed, they are separated by commas.

? The arrow operator. To support lambdas, Java has introduced a new operator “->”,

also known as lambda operator or arrow operator. This arrow operator is required

because we need to syntactically separate the parameter from the body.

? LambdaBody can be an expression or a block. The body could consist of single

statement (in that case no explicit curly braces defining a block are required); such

a lambda body is known as "expression lambda." If there are many statements in a

lambda body, they need to be in a block of code; such a lambda body is known as

“block lambda.”

Compiler performs type inference for lambda expressions:

? The compiler infers the type of the parameters if you do not specify the type

parameters in a lambda function definition. When you specify the type of

parameters, you need to specify all or none; or else you will get a compiler error.

? You can omit the parenthesis if there is only one parameter. But in this case, you

cannot provide the type explicitly. You should leave it to the compiler to infer the

type of that single parameter.

? The return type of the lambda function is inferred from the body. If any of the code in

the lambda returns a value, then all the paths should return a value; or else you will

get a compiler error.

Some examples of valid lambda expressions (assuming that relevant functional interfaces are available):

? (int x) -> x + x

? x -> x % x

? () -> 7

? (int arg1, int arg2) -> (arg1 + arg2) / (arg1 – arg2)

Effectively Final Variables

Lambda functions can refer to local variables from the enclosing scope. The variable needs to be explicitly

declared final or that variable will be treated as effectively final. Effectively final means that the compiler treats

the variable as a final variable and will issue an error if we try to modify it within the lambda function or in the

rest of the function. This behavior of lambdas is similar to accessing variables in outer scope from local and

anonymous classes. The variables they access are also considered effectively final。

Points to Remember

Here are some key points about lambda functions that will help you in the OCPJP 8 exam:

? Lambda expressions can occur only in the contexts where assignment, function calls,

or casts can occur.

? A lambda function is treated as a nested block. Hence, just like a nested block, we

cannot declare a variable with the same name as a local variable in the enclosing

block.

? Lambda functions must return values from all the branches—otherwise it will result

in a compiler error.

? When argument types are declared, the lambda is known as “explicitly typed”; if they

are inferred, it is “implicitly typed.”

? What happens if a lambda expression throws an exception? If it is a checked

exception, then the method in the functional interface should declare that;

otherwise it will result in a compiler error.

读书笔记:

Oracle Certified Professional Java SE 8 Programmer Exam 1Z0-809: A Comprehensive

OCPJP 8 Certification Guide

Copyright ? 2016 by S G Ganesh, Hari Kiran, and Tushar Sharma

ISBN-13 (pbk): 978-1-4842-1835-8

ISBN-13 (electronic): 978-1-4842-1836-5

时间: 2024-10-12 00:03:28

java基础之 Advanced Class Design的相关文章

Java基础常见英语词汇

(转自http://www.jianshu.com/p/2743fe834166) Java基础常见英语词汇(共70个) ['?bd?ekt] ['?:rientid]导向的 ['pr??ɡr?m??]编程OO: object-oriented ,面向对象 OOP: object-oriented programming,面向对象编程 [d?'vel?pm?nt][k?t]工具箱 ['v??tj??l]虚拟的JDK:Java development kit, java开发工具包 JVM:java

java 基础(二)

java 基础(二)java 基础(二) 2016-2-1 by Damon 61. 编写多线程程序有几种实现方式 Java 5以前实现多线程有两种实现方法:一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活. 补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的

Java基础面试题集(一)

Java基础面试题 一.面向对象编程(OOP) 7 二.常见的Java问题 7 2.1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? 7 2.2.JDK和JRE的区别是什么? 8 2.4.是否可以在static环境中访问非static变量? 8 2.5.Java支持的数据类型有哪些?什么是自动拆装箱? 8 2.6.Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思? 8 2.7.Java中,什么是构造函数?什么是构造函数重载?什么是

(CZ深入浅出Java基础)设计模式笔记

一.面向对象思想设计原则 1.单一职责原则 其实就是开发人员经常说的"高内聚,低耦合",也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个.在设计模式中,所有的设计模式都遵循这一原则. 2.开闭原则 核心思想是:一个对象对扩展开放,对修改关闭.其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码.也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到这一点呢?这就需要借助于抽象和

Java基础知识【上】(转载)

http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没有考虑到会坚持往后边写,这次应该是更新该内容.而且很讨厌写基础的东西,内容比较琐碎,而且整理起来总会很多,有可能会打散成两个章节,但是我不保证,有可能一个章节就写完了,所以有时候希望基础的很多内容还是读者自己去看看,我基本保证把基础的内容全部都写出来,见谅.这一个章节写了过后我会把前边那个关于基础类

Java基础课程2—— I/O 的基础操作

Java基础课程2 -- I/O 的基础操作 今天我们将了解一些面向对象编程的基本概念,什么是类.什么是函数 以及了解组成一个程序的四大功能,负责处理数据输入.输出的IO,对计算过程进行控制的逻辑控制.负责对数据进行运算的数值计算.对运行过程中产生的临时变量进行存储的缓存,以及它们是如何互相支撑.协同工作的. 什么是软件? 首先,我们学习编程,但得先弄明白什么是软件? 软件,英文名Software首先由阿兰图灵提出,在软件工程.计算机科学领域,软件即通过计算机,自动化的处理运行指令.数据的计算过

-Java基础-Java介绍

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权:凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记. java的介绍 1.1java简介 Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言. 它最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机.电话.闹钟.烤面包机等家用电器的控制和通讯问题.由于这些智能化家电的市场需求没有预期的高,Sun放弃了该项计划.就在Oak几近失败之时,随着互联网的发展,Sun看到了Oak在计算机

第3篇-JAVA基础

第3篇-JAVA基础 每篇一句 :目标是给梦想一个期限,行动与坚持就是实现梦想的过程 初学心得: 遇到困难或问题,它不是休止符,而是引向你如何解决问题的标识 (笔者:JEEP/711)[JAVA笔记 | 时间:2017-03-26| JAVA基础 Ⅱ] 上篇回顾 上篇文章中我们学习了JAVA底层的运行机制与深入剖析以及解释其中JAVA基础代码的含义 本篇文章将JAVA基础Ⅱ全面剖析解释,因为JAVA基础非常重要,务必要牢记知识点!!! 1.JAVA基础语法格式 JAVA采用unicode编码 1

Java基础学习第五天——方法与数组

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.02.24 lutianfei none 第三章Java基础语法 方法 方法就是完成特定功能的代码块,即函数. 格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2-) { 函数体; return 返回值; } 详细解释: 修饰符,目前就用public static,后详解. 返回值类型:就是功能结果的数据类型. 方法名:符合命名规则即可,方便我们的调用. 参数: 实际参数:就是实际参与运算的.