给大忙人看的Java核心技术笔记(2、面向对象编程)

时间:2023-01-24 17:21:37

对象:对象在函数的基础上添加了一个维度。每个对象可以有自己的状态。状态影响调用方法时返回的结果。

封装:当你使用其他人实现的对象并在对象上调用方法,不需要知道底层是怎样的。

1、Accessor(访问器)和Mutator(更改器)方法

  更改器方法:一个方法改变了调用它的对象。

  访问器方法:方法不改变调用自己的对象,而是返回一个新构造的对象。

  ※为了防止并发访问问题,可以只提供访问器方法,是的对象都是不可变的。(方法不改变调用方法对象本身的状态)

  ArrayList类的Add方法就是更改器方法的典型例子

2、对象引用

  一些语言(C++)中,变量可以持有对象(组成对象状态的bit)。在Java中变量只能持有对象的引用。

  在c/c++中可以修改指针并重写任意位置内存,java引用,只能访问特定对象。

  java中不能写出更新基本类型参数的方法。方法都是获得入参对象的拷贝。

  ※在java中所有参数,对象引用和基本数据类型都是值传递

3、构造对象

  用户可以通过工程方法调用私有构造函数。

  ※构造函数一定没有返回值!

public Employee(double salary){
  this("", salary);//调用构造函数Employee(String, double)
  //这里this不是正被构造对象的引用,是一种特殊语法,只用在同类的另一个构造函数调用中  
}

  可以使用初始化块给类的成员设初值(就是用括号括起来的一段代码)

  可以将实例变量声明为final,这样在构造之后不能set也没有set方法。

//当使用可修改对象的引用时,final只是声明该引用永不改变。
public class Person{
  private final ArrayList<Person> friends = new ArrayList<>(); 
}

  方法可以修改friends引用的数组列表,但不能用其他对象代替。特别是不能为null。

4、静态变量和方法

  在类中将变量声明为static,那么该变量属于类,而不是对象,否则每个对象都有一份实例变量的拷贝。

  static final 静态常量

  虽然System.out 被声明成final,但是还是有个setOut方法,将Sysout设置到不同的流上,由于该方法是本地方法,不受java的管制。

  静态初始化块 static{}

  虽然可以在对象上调用静态方法,但是这样是不推荐的!静态方法不能访问实例变量,只能访问本类的静态变量。

  静态方法最常见的就是工厂方法。AClass.getAInstance();工厂方法还能返回共享对象,实现单例模式等等。。。

5、包

  包的主要原因是保证类名的唯一性。java标准类库的包名以java或javax开始。

  运行javac时带上-d让Class文件会产生在单独的目录中,不会搞乱源代码树,class文件也有正确的子目录结构。

  将class打包到JAR(归档文件)中,可以用JDK的jar工具

  jar cvf library.jar com/mycompany/*.class    通常jar文件使用ZIP格式,还有个“pack200”选项指定压缩模式

  java -jar program.jar 来运行程序

  java -classpath .:../libs.jar(Linux,  在Windows中用;而不是用:来分隔路径元素)。也可以用../libs/\* 来导入目录下所有文件(UNIX中,禁止使用*防止Shell命令进一步扩展)

  javac默认总是在当前目录寻找文件,如果没有设置classpath则默认由“.”目录组成。如果你设置了类路径(classpath)并忘记包含“.”目录,程序可以正常编译。但将无法运行。

  除了使用-classpath选项,还可以设置环境变量

    export CLASSPATH=.:/home/username/project/libs/\*  (Linux)

    SET CLASSPATH=.;C:\Users\username\project\libs\*  (windows)

  ※如果一个类、方法、变量不指定public也不指定private,他就可以被同一个包中所有方法访问。

  一个源文件可以包含多个类,但最多只有一个可以声明为public。如果一个源文件有个public类,那么文件名和类名必须一致

  想让包只使用自己内部的类,不被外部类干扰(比如包内导入1.5API,不会因为外部使用的1.6的API而被覆盖)可以设置manifest文件将jar包封闭

Name: com/mycompany/util
Sealed: true

  运行jar:

  jar cvfm library.jar manifest.txt com/mycompany/*/*.class

  导入包:

    可以使用  import java.util.*;导入包下的所有类,但不能导入包下的包 

6、嵌套类

  静态嵌套类:

     

1 public class Invoice{
2   private static class Item{}  
3 }

  Item是private的所以只有Invoice能访问。若是public的任何人都可以通过Invoice.Item来构建Item对象

  内部类:

    就是静态嵌套类去掉static。

 

1 public class Network{
2   public class Member{
3         public void leave(){
4             members.remove(this);
5         }
6     }      
7 }        

    内部类的方法可以访问它的外部类的实例变量,每个内部类对象都有自己外部类对象的引用

      members.remove(this);  实际含义为  outer.members.remove(this);

    当嵌套类的实例不需要知道它属于外部类的那个实例时,使用静态嵌套类。只有当这种信息重要时,才使用内部类

    ※内部类通过它的外部类实例也能调用外部类的方法。

 1   public class Network{
 2     public class Member {
 3       ...
 4       public void leave(){
 5         unenroll(this);
 6       }
 7     }
 8     
 9     public Member enroll(String name){}
10     public void unenroll(Member m){}
11   }

    outer.unenroll(this);

    ※在实际的使用中outer应该替换为OuterClass.this也可以什么都不写

1 public void leave(){
2   Network.this.members.remove(this);  
3 }

   可以在外部类的任何实例上调用内部类的构造函数

    

1 Network.Member wilma = myFace.new Member("wilma ")

7、JavaDoc

  运行命令  javadoc -d outputDir  package1 package2.....