对象:对象在函数的基础上添加了一个维度。每个对象可以有自己的状态。状态影响调用方法时返回的结果。
封装:当你使用其他人实现的对象并在对象上调用方法,不需要知道底层是怎样的。
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.....