(四)对象与类
1. 在面向对象(OOP)中,不必关心对象的具体实现,只要能够满足用户的需求即可。
2. 面向过程首先确定如何操作数据,然后再决定如何组织数据,以便于数据操作,而面向对象却调换了这个次序,将数据放在第一位,然后在考虑操作数据的算法
3. 类是构造对象的模版或蓝图,由类构造对象的过程称为创建类的实例,对象中的数据称为实例域,操作数据的过程称为方法。对象状态的改变必须通过调用方法实现。
4. 对象的三个主要特性:
- 对象的行为:可以对对象施加哪些操作,或可以对对象施加哪些方法
- 对象的状态:当施加那些方法时,对象如何响应
- 对象的标示:如何辨别具有相同行为与状态的不同对象
5. 类之间的关系
- 依赖:uses-a 如果一个类的方法操纵另一个类的对象,我们就说一个类依赖于另一个类。应该尽可能的将互相依赖的类减至最少,也就是让类之间的耦合度最小
- 聚合:has-a 例如一个对象包含一些其他对象。聚合意味着类A对象包含类B对象
- 继承:is-a 一般而言,如果类A扩展类B,类A不仅包含类B的方法,还会拥有一些额外的功能。
6. 统一建模语言(UML):
  
7. 关系:Date data = new Date();//表达式new Date()构造了一个Date类型的对象,并且它的值是对新创建对象的引用,这个应用存储在变量date中。可以将Java的对象变量看作是C++的对象指针
8. 所有的Java对象都存储在堆中,当一个对象包含另一个对象变量时,这个变量依然包含着指向另一个堆对象的指针。
9. 构造器与其他方法有一个重要的不同。构造器总是伴随着new操作符的执行被调用,而不能对一个已经存在的对象调用构造器在达到重新设置实例域的目的。
- 构造器与类同名
- 每个类可以有一个以上的构造器
- 构造器可以有0个、1个、或多个参数
- 构造器没有返回值
- 构造器总是伴随着new操作一起调用
- 不要在构造器中定义与实例域重名的局部变量
10. 在java程序设计语言中,所有的方法都必须在类的内部定义,但并不表示他们时内联方法,是否将某个方法设置为内联方法是java虚拟机的任务。
11. 在有些时候,需要获得或设置实例域的值,应该提供下面三项内容:
- 一个私有的数据域
- 一个共有的域访问器方法
- 一个公有的域更改器方法
12. 可以将实例域定义为final。构建对象时必须初始化为这样的域。也就是说,必须确保在每一个构造器执行之后,这个域的值被设置。并且在后面的操作中,不能够再对他进行修改。但是像这样的private final Date hiredate;变量中的对象引用在对象构造器之后不能改变,而并不意味着hiredate对象是一个常量。实际上任何方法都可以对hiredate引用的对象调用setTimer方法。
13. 如果将域定义为static,每个类中只有一个这样的域,而每一个对象对于所有的实例域却都有自己的一份拷贝。这个类的所有实例将共享一个static域,他属于类,而不属于任何一个独立的对象。
14. 我们常用的System.out方法其实是这样的
public class System{
...
public staic final PrintStream out = ...;
...
}
15. 静态方法不能操作对象,所以不能在静态方法中访问实例域,但是静态方法可以访问自身类中的静态域。static的含义是属于类且不属于类对象的变量和函数。
16. Java程序设计语言总是按值调用,没有引用调用,也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给他的任何参数变量的内容。
例如:double percent = 10;
harry.raiseSalary(percent);
不必理睬这个方法的具体实现,在方法调用之后,percent的值还是10.
17. 方法参数共有两种类型
- 基本数据类型
- 对象引用
不管是哪种,都先形成一个拷贝,但是对于值参数的修改没有保留下来,但是对于对象参数的修改保留着下来,因为他们都是指向同一个对象
|  |  | 
18. swap功能的实现
import java.util.*;
public class SwapApp{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要交换的两个数值:");
        int numOne = sc.nextInt();
        int numTwo = sc.nextInt();
        System.out.println("交换前的两个数值为:numOne="+numOne+"   numTwo="+numTwo);
        System.out.println("开始交换两个数值...");
        Swap sw = new Swap(numOne,numTwo);
        System.out.println("交换后的两个数值为:numOne="+sw.getA()+"   numTwo="+sw.getB());
    }
    public static class Swap<T>{
        private final T a;
        private final T b;
         public Swap(T a, T b){
             this.a = b;
             this.b = a;
         }
         public T getA(){
             return a;
         }
         public T getB(){
             return b;
         }
    }
}

19. 如果多个方法有相同的名字,不同的参数,便产生了重载。java 允许重载任何方法,要完整的描述一个方法,需要指出方法名以及参数,这叫做方法签名。值得注意的是返回类型不是签名的一部分,也就是说,不能有两个名字相同,参数类型也相同却返回不同类型值的方法。
20. 如果在构造器中没有显式的给域赋予初值,那么就会被自动的赋为默认值:数值为0,布尔型为false,对象引用为null。如果在编写一个类时没有编写构造函数,那么系统就会提供一个无参数构造器,这个构造器将所有的实例域设置为默认值。
21. 仅当没有提供任何构造器的时候,系统才会提供一个默认的构造器。如果在编写类的时候,给出了一个构造器,哪怕时很简单的(假设含有参数),要想让这个类的用户采用无参构造器,就必须提供一个默认的构造器即不带参数的构造器
22. 可以在一个构造器中调用同一个类中的另一个构造器。
public Class Emploee{
    private String company;
    private double salary;
    public  Emploee(double aSalary){
        this("oracle", aSalary);
    }
    public  Emploee(String aCompany, double aSalary){
        this.company = aCompany;
        this.salary = aSalary;
    }
}
23. 初始化数据域的方法:
- 在构造器中设置值
- 在声明中赋值
- 在初始化块中设置值
24. 由于java 有自动的垃圾回收器,不需要人工回收内存,所以java不支持析构器。
25. java使用包的主要原因之一是确保类名的唯一性。package。如果没有在源文件中放置package语句,这个源文件中的类就被放置在一个默认包(default package)中。编译器对文件xxx.java进行操作,而java解释器加载类xxx.class
26. 类设计的技巧
- 一定要保证数据私有
- 一定要对数据初始化
- 不要在类中使用过多的基本类型,可以将相关的实例域包装在一个新的类中
- 不是所有的域都需要独立的域访问器和域更改器
- 将职责过多的类进行分解

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号