Previous slide Next slide Toggle fullscreen Open presenter view
面向对象编程
概念回顾
面向对象编程首先认识待解决问题所涉及的基本对象和他们间的相互关系,然后将这些现实对象映射到计算机中,实现计算机对现实问题的模拟,将“问题空间”直接映射到“解空间”。
Class
class Human {
int age;
boolean gender;
void walk () {};
}
UML
PlantUML (http://www.plantuml.com/)
初始化(构造)
从”对象模版“生成“对象实例“
Human you = new Human ();
每个对象拥有一份属性拷贝
对象共享方法(代码)的定义
每个对象有一个标识(id,内存地址)
通过对象引用(Object Reference)可访问对象方法和属性
Object Instances in Heap
class Cat {}
Cat myCat = new Cat ();
Copy by Reference
class Cat {}
Cat myCat = new Cat ();
Cat c = myCat;
构造函数/器(Constructor)
类的设计者通过构造器保证每个对象的初始化;
如果一个类有构造器,那么 Java 会在用户使用对象之前(即对象刚创建完成)自动调用对象的构造器方法,从而保证初始化;
构造器方法名与类名相同,不需要符合首字母小写的编程风格。
构造器示例
class Human {
int age; boolean gender;
Human(){
age = 0 ; gender = false ;
}
Human(int age){
gender = true ; this .age = age;
}
Human(boolean gender){
this (0 );
this .gender = gender;
}
}
无参构造器
如果你创建一个类,类中没有构造器,那么编译器就会自动为你创建一个无参构造器。
class Bird {}
public class DefaultConstructor {
public static void main (String[] args) {
Bird bird = new Bird ();
}
}
But
一旦你显式地定义了构造器(无论有参还是无参),编译器就不会自动为你创建无参构造器。
class Bird2 {
Bird2(int i) {}
Bird2(double d) {}
}
public class NoSynthesis {
public static void main (String[] args) {
Bird2 b2 = new Bird2 (1 );
Bird2 b3 = new Bird2 (1.0 );
}
}
初始化顺序
在类中变量定义的顺序决定了它们初始化的顺序。即使变量定义散布在方法定义之间,它们仍会在任何方法(包括构造器)被调用之前得到初始化。
class Window {
Window(int marker) { System.out.println("Window(" + marker + ")" ); }
}
class House {
Window w1 = new Window (1 );
House() { System.out.println("House()" ); w3 = new Window (33 ); }
Window w2 = new Window (2 );
void f () { System.out.println("f()" ); }
Window w3 = new Window (3 );
}
Continue
public class OrderOfInitialization {
public static void main (String[] args) {
House h = new House ();
h.f();
}
}
输出什么?
静态变量
class Human {
static int total;
int age;
boolean gender;
Human(){
Human.total++;
age = 0 ;
gender = false ;
}
...
}
Static Blocks
class Human {
static int total;
static {
total = 2 ;
}
int age;
boolean gender;
Human(){
Human.total++;
age = 0 ;
gender = false ;
}
...
}
Instance initialization
class Man {
Object girlfriend;
{
girlfriend = new Dog ();
}
...
}
数组初始化
int a1[];
int [] a1 = {1 , 2 , 3 , 4 , 5 };
int [] a;
Random rand = new Random (47 );
a = new int [rand.nextInt(20 )];
数组赋值
public class ArraysOfPrimitives {
public static void main (String[] args) {
int [] a1 = {1 , 2 , 3 , 4 , 5 };
int [] a2;
a2 = a1;
for (int i = 0 ; i < a2.length; i++) {
a2[i] += 1 ;
}
for (int i = 0 ; i < a1.length; i++) {
System.out.println("a1[" + i + "] = " + a1[i]);
}
}
}
可变参数列表-数组实现
class A {}
public class VarArgs {
static void printArray (Object[] args) {
for (Object obj: args) { System.out.print(obj + " " ); }
System.out.println();
}
public static void main (String[] args) {
printArray(new Object [] {47 , (float ) 3.14 , 11.11 });
printArray(new Object [] {"one" , "two" , "three" });
printArray(new Object [] {new A (), new A (), new A ()});
}
}
或者
public class NewVarArgs {
static void printArray (Object... args) {
for (Object obj: args) { System.out.print(obj + " " ); }
System.out.println();
}
public static void main (String[] args) {
printArray(47 , (float ) 3.14 , 11.11 );
printArray("one" , "two" , "three" );
printArray(new A (), new A (), new A ());
printArray((Object[]) new Integer [] {1 , 2 , 3 , 4 });
printArray();
}
}
Enum
怎么理解?
Although enums appear to be a new data type, the keyword only produces some compiler behavior while generating a class for the enum, so in many ways you can treat an enum as if it were any other class. In fact, enums are classes and have their own methods.
enum GENDER {
MALE, FEMALE, NOTTELLING
}
public static void main (String[] args) {
GENDER gender = GENDER.MALE;
System.out.println(gender.toString() + " " + gender.ordinal())
}
Stop-and-Copy
Mark-and-Sweep
名空间 package
package com.java;
class Human {
}
package com.java.another;
import com.java.Human;
class Society {
}
CLASSPATH
The class loading problem.
?
set CLASSPATH=.:/path/to/some/folder:/path/to/other.jar
java com.java.Human
cd /path/to/some/folder/
java Human
访问控制
修饰符
public
protected
private
default
public
对于每个人都是可用(Interface access)
enum Appearance {
BEAUTIFUL, UGLY
}
public class Human {
public Appearance appearance;
}
protected
Inheritance access
public class Human {
protected float money;
}
注:此例并不恰当
private
You can't touch that!
enum Mood {
GOOD, BAD
}
public class Human {
private Mood mood;
}
default
Package friendly
enum Performance {
GOOD, BAD
}
public class Human {
Performance performance;
}
封装 Encapsulation
Encapsulation is to hide the implementation details from users
Encapsulating for
Flexibility
Reusability
Maintainability
代码重用(复用)
途径
Composition
Inheritance
Delegation
Composition
强合成:“部分”的生命期不能比“整体”还要长
public class Heart {
...
}
public class Liver {
...
}
public class Human {
private Heart battery;
private Liver screen;
...
}
弱合成
除了“强合成”关系外,还存在“弱合成”关系
Aggregation 聚合: “部分”可独立存在
Association 关联: 对象可以向另一个对象通过某种方式发送消息
Inheritance
继承是所有面向对象语言的一个组成部分。事实证明,在创建类时总是要继承,因为除非显式地继承其他类,否则就隐式地继承 Java 的标准根类对象(Object)。
初始化基(父)类 first
class Art {
Art() { System.out.println("Art constructor" ); }
}
class Drawing extends Art {
Drawing() { System.out.println("Drawing constructor" ); }
}
public class Cartoon extends Drawing {
public Cartoon () { System.out.println("Cartoon constructor" ); }
public static void main (String[] args) {
Cartoon x = new Cartoon ();
}
}
用委托实现代码复用
In software engineering, the delegation pattern is an object-oriented design pattern that allows object composition to achieve the same code reuse as inheritance.
final
的变量
常量声明(经常和static
关键字一起使用)
public static final int i = 0 ;
i=1 ;
final
方法
代表这个方法不可以被子类的方法重写。
class Father extends Man {
public final void hitChild () {
}
}
class Son extends Father {
@Override
public final void hitChild () {
}
}
“父类中这件事已经做得够好了,子类无法超越”
final
类
final class Father extends Man {
}
class Son extends Father {
}
“老子整个已经不可超越”
Polymorphism
多态性是指对象能够有多种形态。
多态是”继承“的产物
class Man extends Human {
...
}
class Human extends Creature {
...
}
class Creature extends Being {
...
}
多态意味着什么?
class Creature extends Being {
public void eat () { System.out.println("eating" ); }
}
class Human extends Creature {
@Override
public void eat{ System.out.println("cooking...eating" ) }
}
class Woman extends Human {
@Override
public void eat{ System.out.println("cooking...photoing...eating" ); }
}
Being you = new Woman ();
you.eat();
再举个例子
class Shape {
void draw () { System.out.println("Draw Shape" ); }
}
class Circle extends Shape {
void draw () { System.out.println("Draw Circle" ); }
}
class Triangle extends Shape {
void draw () { System.out.println("Draw Triangle" ); }
}
class Square extends Shape {
void draw () { System.out.println("Draw Square" ); }
}
public class Test {
public static void main (String[] args) {
Shape[] shapes = {new Circle (), new Triangle (), new Square ()};
for (Shape s : shapes){
s.draw();
}
}
}
执行结果?
再看一个例子
class Shape {
private void draw () { System.out.println("Draw Shape" ); }
void show () { draw(); }
}
class Circle extends Shape {
void draw () { System.out.println("Draw Circle" ); }
}
public class Test {
public static void main (String[] args) {
Shape s = new Circle ();
s.show();
}
}
执行结果?
多态形成的条件
实际上是由Java中的”动态绑定“机制造成的。
抽象类
当一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类。 比如:
class Human {
public void meetLouisVuitton () {
}
}
Abstract Class
abstract class Human {
public abstract void meetLouisVuitton () ;
}
class Man extends Human {
@Override
public void meetLouisVuitton () {
pass();
}
}
class Woman extends Human {
@Override
public void meetLouisVuitton () {
enter();
}
}
Why?应对不确定。
Interface
当所有行为都不确定时,干脆来一份Interface。
接口比抽象类更抽象。
接口是用来建立类与类之间的协议(protocol)。
举个例子
public interface Communicate {
public String talkTo (String message) ;
}
public Man extends Human implements Communicate {
...
public String talkTo (String message) {
return process(message);
}
}
public Woman extends Human implements Communicate {
...
public String talkTo (String message) {
return "我不听我不听我不听" ;
}
}
实现多个接口
interface A {
public void a () ;
}
interface B {
public void b () ;
}
class C implements A ,B {
public void a () { ... }
public void b () { ... }
}
为什么Java不支持多继承多个父类但支持实现多个接口?
接口中的成员变量
成员变量必须是public static final
为什么? 公有化,标准化、规范化。



.element height="40%" width="40%"
---
## Delegating
什么叫委托?举个不太合适的例子:
```java
public class Car {
public Window[] windows = new Window[4];
}
public class Jetta extends Car{
}
Car myCar = new Jetta();
//手摇式玻璃
myCar.windows[0].open();
```
---
## Delegating
```java
public class Car {
public Window[] windows = new Window[4];
}
public class Tesla extends Car{
public void openWindow(int i){
this.windows[i].open(); //delegate
}
}
Car hisCar = new Tesla();
//自动式玻璃
hisCar.openWindow(1);
```
---
## A system class
```java
public class Window {
private Button btnClose;
private void btnCloseClicked(){
///???
}
}
```
---
## Customizing it by extending it
```java
public class MyWindow extends Window {
private Button btnClose;
private void btnCloseClicked(){
// bala bala
}
}
```
---
## Or implementing a delegate
```java
public class Window {
private Button btnClose;
private WindowDelegate delegate;
private void btnCloseClicked(){
delegate.windowClosing();
}
}
public class WindowDelegate {
public windowClosing(){
//bala bala
}
}
```
<span style="color:red">Why?</span> <!-- .element: class="fragment"
.element: class="fragment"
.element: class="fragment"