--java
1,类的关系
• Dependence (“uses–a”):依赖,一个类use另一个类
• Aggregation (“has–a”):聚合,一个类中的成员是另一个类
• Inheritance (“is–a”):继承
extra:关于Association以及Aggregation和Composition
从代码实现的角度上讲:三者都是以属性出现,
其中Association中作为属性出现时,不需要对其进行强制赋值,只要在使用是对其进行初始化即可。
Aggregation中作为属性出现时,需要在构造器中通过传递参数来对其进行初始化。Composition中作为属性出现时,需要在整体的构造器中创建部分的具体实例,完成对其的实例化。
从数据库的层面上来讲:
Association不需要被级联删除,
Aggregation不需要被级联删除,
Composition是需要被级联删除的。
2, 关于java日期类的一些使用方法(Calendar,GregorianCalendar)
创建日期对象: Calendar d = new GregorianCalendar();
- 今天是这个月的几号:d.get(Calendar.DAY_OF_MONTH)
- 得到这个星期的星期几(周日开始1-7):d.get(Calendar.DAY_OF_WEEK)
- 一周的第一天:d.getFirstDayOfWeek()
- 前进/后退一天:d.add(Calendar.DAY_OF_MONTH,1)/d.add(Calendar.DAY_OF_MONTH,-1);
- 这个月的月份:d.get(Calendar.MONTH)
...待续
3, java的方法
- 注意定义setter方法的时候,将返回的对象先克隆:
class A
{
. . .
[b]public Date getDate()[/b]
{
return day;
}
. . .
private Date hireDay;
}
和
class A
{
. . .
public Date getHireDay()
{
[b]return (Date) day.clone();[/b]
}
. . .
}
- 设计者定义私有方法是因为不希望在外部使用它,并且能够方便的丢弃掉;
- 使用静态方法:当不需要访问对象状态时,当仅需要访问静态成员时;
- java中方法参数传递不是传引用,而是将引用进行传值,方法不能改变原类型的值,可以改变对象状态,不能使一个对象引用到另一个对象;
4, 类的设计原则
- 保持数据是private
- 总是要初始化数据
- 不要再类中使用过多的基本类型数据
- 不用所有的数据成员都设置get set 方法
- 定义class标准顺序:public features - package scope features - private features
而在每一块内又可这样:instance methods - static methods - instance fields -
static fields
- 将职责过大的class 分成多个class
- 为类和方法起有意义的名字
-- Java数据类型,操作符以及流程控制
1,包装器类
Integer, Long, Float, Double, Short, Byte, Character, Void, and Boolean, 前六个继承自Number类;
包装器类 是不可变的包装后就不能改变值,他们也是final的 不能被继承;
2,对象类,基本类型间的转换
Ingeter -> int: IngeterObject.intValue()
Integer -> String: Ingeter.toString(int i)/ toString(int i, int radix)
String -> int: Integer.parseInt(String s)/parseint(String s, int radix)
String -> Integer: Integer.valueOf(String s)/valueOf(String s, int radix)
String -> Number: IngeterObject.parse(String s)
3,enum类型
可以有构造函数,方法,成员,
public enum EnumTest {
TEST1("ONE"), TEST2("TWO"), TEST3("THREE");
private EnumTest(String s){
this.ss =s;
}
public String getSS(){
return this.ss;
}
private String ss;
public static void main(String[] args) {
TestEnum.main(null);
}
}
class TestEnum{
public static void main(String[] args) {
System.out.println(EnumTest.TEST1.toString()); //TEST1
System.out.println(EnumTest.TEST1.getSS()); //ONE
EnumTest etest =Enum.valueOf(EnumTest.class, "TEST1");
System.out.println(EnumTest.values()); //return EnumTest[]
}
}
-- Java继承,封装与多态
[u]1.java的抽象类和接口
抽象类:
-如果abstract类中有一个方法未被子类实现,那么这个类仍是一个abstract类(只要还存在一个abstract的成员或方法,那么类必须被abstract修饰);
-abstract类的成员默认是default类型并且可以被继承;
-只能是单重继承;
以上提到abstract类不可以被实例化,但是可以讲其数组化:
Abstract class A{
public int a;
abstract int getInt();
public static void main(String[] args) {
A abs = new A(); // fail
A[] abs = new A[2]; //passed
}
}
注: 此规则一样适用于interface;
接口:
- 接口本身的访问权限和class一样,具有全局,包,保护,私有(inner class)
- interface中的成员默认就是 public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;
- interface中的方法默认都是 public,abstract 类型的。
- 可以多个一起被实现;
- 实现了一个interface那么必须实现它的所有方法,方法是public的;[/u]
2, final
一个class是final的, 那么它的方法也自动是final的,,但是成员不是自动final
3, A是父类, B继承自A,A 有方法f1,f2, B有方法f2,f3 (都是public的情况)
test1:
A a = new A(); //declare和reference都是A
a.f1;
a.f2; //执行A的f1 和f2
B b =(B)a; //A cast to B, 此时编译不会报错,但是运行报错;可以使用instanceof 来检测,b instanceof A , 此时是false;
test2:
A a = new B(); //这是指向B的内存区域的
a.f1; // 调用B中的 f1
a.f2; //B中被覆写的f2
a.f3; //无法调用这个
B b =(B)a;
b.f1;
b.f2;
b.f3; //f1,f2,f3调用B的 正常无错误
test3:
B b = new B();
b.f1;
b.f2;
b.f3; //正常调用
A a = b;
a.f1;
a.f2; //以上2个正常
a.f3; //这个无法调用
test4:
B b = (B) new A(); //编译通过,运行报错; 比较奇葩
test5:
B b = new B();
A a = (A)b;
a.f1; //调用B的f1
a.f2; // 调用B的f2
a.f3; //无法调用
继续实验加上一个C类继承自B,即B的子类, 提供方法f1,f3,f4
test6:
A a = new C();
a.f1; // 调用C中的 f1
a.f2; // 调用C的f2
a.f3; //
a.f4; //无法调用后2个
C c =(C)a;
c.f1; // C的f1
c.f2; // B的
c.f3; // C的
c.f4; //C的
test7:
C c = new C();
c.f1;
c.f2;
c.f3;
c.f4; //正常调用
A a = c;
a.f1; //C的f1
a.f2; //C的f2
a.f3;
a.f4; //后2个无法调用
test8:
C c = new C();
A a = (B)c;
a.f1;
a.f2; //C的f1, f2
a.f3;
a.f4; //后2个无法调用
其他的基本相同,逻辑差不多;
4, 父类A中的私有变量在子类B中的访问
class A {
private String s = "";
A(String ss) {
this.s = ss;
}
public String getS() {
return this.s;
}
}
public class B extends A {
private String s="";
B(String ss, String ss2) {
super(ss);
this.s = ss2;
}
public static void main(String[] args) {
B b = new B("123","456");
System.out.println(b.getS());
}
}
结果: 123
原因:父类的方法在子类中继承,实际是子类对父类方法的一个引用,如果子类中有方法(getS)覆写了父类中继承来的方法(getS), 那么结果是456;
5,构造函数和继承
- 当类没有声明构造函数的时候,编译器会自动生成一个无参构造函数,将所有实例成员设置成默认值;如果有构造函数就不会自动生成默认无参构造;
- 子类只继承父类的默认构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类继承到任何构造函数。
- 子类从父类处继承来的父类默认构造函数,不能成为子类的默认构造函数。
- 创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。
extra:子类继承的时候,必须调用父类的构造函数;这时它会默认调用继承父类的无参构造函数;如果父类没有默认无参构造函数,那么只能在子类构造函数第一行加super(XXX)来调用显示调用父类构造函数;
6,关于继承的一些有用建议:
- 公共的operation或fields,放在父类中
- 不要使用protected的field
- 继承应用到“is-a”模型中
- 除非继承的方法有意义,否则别用继承
- 当覆盖一个方法的时候不要改变它预期的行为
- 利用多态性,而不是用类型信息来判断
- 不要过度使用反射
7, 构造函数的基本执行顺序 (无静态情况,静态最优先)
- 所有数据成员被初始化为默认值(0, false, or null).
- 按照声明顺序初始化 块 中的所有成员.
- 如果调用的构造函数第一行调用了另外一个构造函数,那么第二个构造函数执行.
- 调用的构造函数执行.
-- 反射
1,得到Class的几种途径
Class cl = e.getClass();
Class cl = Class.forName(className);
Class cl1 = Date.class; or Class cl2 = int.class;
注:比较两个Class类型相等 直接用==
2,创建对象
Class.newInstance() 调用默认构造函数
一些snippet:
1,Modifier.toString(m.getModifiers()) 得到修饰符
2,
{
String brackets = "";
while (cls.isArray()) { // 转化多维数组时
brackets += "[]";
cls = cls.getComponentType();
}
String full_name = cls.getName();
int pos = full_name.lastIndexOf('.');
if (pos != -1)
full_name = full_name.substring(pos + 1);
return full_name + brackets;
}
3,
注:getFields, getMethods, and getConstructors 得到public的,并且可以得到父类的public的method和field但是不能得到constructor;getDeclaredFields, getDeclaredMethods, and getDeclaredConstructors能得到本类中声明的所有的方法成员和构造函数;
-- 克隆对象
clone三部曲。
1 声明实现Cloneable接口。
2 调用super.clone拿到一个对象,如果父类的clone实现没有问题的话,在该对象的内存存储中,所有父类定义的field都已经clone好了,该类中的primitive和不可变类型引用也克隆好了,可变类型引用都是浅copy。
3 把浅copy的引用指向原型对象新的克隆体。
考虑一个类对clone的态度,有如下几种。
1 公开支持:好吧,按照clone三部曲实现吧。前提是父类支持(公开或者默默)。
2 默默支持:不实现Cloneable接口,但是在类里面有正确的protected的clone实现,这样,该类不支持clone,但是它的子类如果想支持的话也不妨碍。
3 不支持:好吧,为了明确该目的,提供一个抛CloneNotSupportedException 异常的protected的clone实现。
4 看情况支持:该类内部可以保存其他类的实例,如果其他类支持则该类支持,如果其他类不支持,该类没有办法,只有不支持。
-- 内部类
使用内部类的理由:
- 内部类能够访问定义它们的类中的数据,包括private的
- 同一包中的内部类能够被其他类(外部)给隐藏起来
- 当你想定义回调函数时,使用匿名内部类将非常方便,使你不用编写很多代码.
内部类持有外部类的引用,在内部类的默认构造函数中会创建一个到外部类的引用;
默认构造函数类似这样:
public Inner(Outer out) // automatically generated code
{
this.outer = out;
}
-- 代理
-- 容器类
1,数组和列表
数组大小确定后,内部自动赋值,但是list创建的时候指定大小,如果里面不存值便不占用存储空间:
int[] array = new int[100];
ArrayList<Integer> list = new ArrayList<Integer>(100);
array[50]=4; // 第50个元素设置为4
list.add(50,4); // fail, 目前list大小为0, 不能加入第50个item,要从头开始添加;
for(int a : array)
System.out.println(a); //第50个为4,其余为0
-- 其他
1.Eclipse 遇到错误提示“Failed to create the Java Virtual Machine ”
问题解决:
找到eclipse目录下的eclipse.ini 编辑这段:
--launcher.XXMaxPermSize
256M //也可能其他值 改成128M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m //也可能其他值 改成128M
1,类的关系
• Dependence (“uses–a”):依赖,一个类use另一个类
• Aggregation (“has–a”):聚合,一个类中的成员是另一个类
• Inheritance (“is–a”):继承
extra:关于Association以及Aggregation和Composition
从代码实现的角度上讲:三者都是以属性出现,
其中Association中作为属性出现时,不需要对其进行强制赋值,只要在使用是对其进行初始化即可。
Aggregation中作为属性出现时,需要在构造器中通过传递参数来对其进行初始化。Composition中作为属性出现时,需要在整体的构造器中创建部分的具体实例,完成对其的实例化。
从数据库的层面上来讲:
Association不需要被级联删除,
Aggregation不需要被级联删除,
Composition是需要被级联删除的。
2, 关于java日期类的一些使用方法(Calendar,GregorianCalendar)
创建日期对象: Calendar d = new GregorianCalendar();
- 今天是这个月的几号:d.get(Calendar.DAY_OF_MONTH)
- 得到这个星期的星期几(周日开始1-7):d.get(Calendar.DAY_OF_WEEK)
- 一周的第一天:d.getFirstDayOfWeek()
- 前进/后退一天:d.add(Calendar.DAY_OF_MONTH,1)/d.add(Calendar.DAY_OF_MONTH,-1);
- 这个月的月份:d.get(Calendar.MONTH)
...待续
3, java的方法
- 注意定义setter方法的时候,将返回的对象先克隆:
class A
{
. . .
[b]public Date getDate()[/b]
{
return day;
}
. . .
private Date hireDay;
}
和
class A
{
. . .
public Date getHireDay()
{
[b]return (Date) day.clone();[/b]
}
. . .
}
- 设计者定义私有方法是因为不希望在外部使用它,并且能够方便的丢弃掉;
- 使用静态方法:当不需要访问对象状态时,当仅需要访问静态成员时;
- java中方法参数传递不是传引用,而是将引用进行传值,方法不能改变原类型的值,可以改变对象状态,不能使一个对象引用到另一个对象;
4, 类的设计原则
- 保持数据是private
- 总是要初始化数据
- 不要再类中使用过多的基本类型数据
- 不用所有的数据成员都设置get set 方法
- 定义class标准顺序:public features - package scope features - private features
而在每一块内又可这样:instance methods - static methods - instance fields -
static fields
- 将职责过大的class 分成多个class
- 为类和方法起有意义的名字
-- Java数据类型,操作符以及流程控制
1,包装器类
Integer, Long, Float, Double, Short, Byte, Character, Void, and Boolean, 前六个继承自Number类;
包装器类 是不可变的包装后就不能改变值,他们也是final的 不能被继承;
2,对象类,基本类型间的转换
Ingeter -> int: IngeterObject.intValue()
Integer -> String: Ingeter.toString(int i)/ toString(int i, int radix)
String -> int: Integer.parseInt(String s)/parseint(String s, int radix)
String -> Integer: Integer.valueOf(String s)/valueOf(String s, int radix)
String -> Number: IngeterObject.parse(String s)
3,enum类型
可以有构造函数,方法,成员,
public enum EnumTest {
TEST1("ONE"), TEST2("TWO"), TEST3("THREE");
private EnumTest(String s){
this.ss =s;
}
public String getSS(){
return this.ss;
}
private String ss;
public static void main(String[] args) {
TestEnum.main(null);
}
}
class TestEnum{
public static void main(String[] args) {
System.out.println(EnumTest.TEST1.toString()); //TEST1
System.out.println(EnumTest.TEST1.getSS()); //ONE
EnumTest etest =Enum.valueOf(EnumTest.class, "TEST1");
System.out.println(EnumTest.values()); //return EnumTest[]
}
}
-- Java继承,封装与多态
[u]1.java的抽象类和接口
抽象类:
-如果abstract类中有一个方法未被子类实现,那么这个类仍是一个abstract类(只要还存在一个abstract的成员或方法,那么类必须被abstract修饰);
-abstract类的成员默认是default类型并且可以被继承;
-只能是单重继承;
以上提到abstract类不可以被实例化,但是可以讲其数组化:
Abstract class A{
public int a;
abstract int getInt();
public static void main(String[] args) {
A abs = new A(); // fail
A[] abs = new A[2]; //passed
}
}
注: 此规则一样适用于interface;
接口:
- 接口本身的访问权限和class一样,具有全局,包,保护,私有(inner class)
- interface中的成员默认就是 public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;
- interface中的方法默认都是 public,abstract 类型的。
- 可以多个一起被实现;
- 实现了一个interface那么必须实现它的所有方法,方法是public的;[/u]
2, final
一个class是final的, 那么它的方法也自动是final的,,但是成员不是自动final
3, A是父类, B继承自A,A 有方法f1,f2, B有方法f2,f3 (都是public的情况)
test1:
A a = new A(); //declare和reference都是A
a.f1;
a.f2; //执行A的f1 和f2
B b =(B)a; //A cast to B, 此时编译不会报错,但是运行报错;可以使用instanceof 来检测,b instanceof A , 此时是false;
test2:
A a = new B(); //这是指向B的内存区域的
a.f1; // 调用B中的 f1
a.f2; //B中被覆写的f2
a.f3; //无法调用这个
B b =(B)a;
b.f1;
b.f2;
b.f3; //f1,f2,f3调用B的 正常无错误
test3:
B b = new B();
b.f1;
b.f2;
b.f3; //正常调用
A a = b;
a.f1;
a.f2; //以上2个正常
a.f3; //这个无法调用
test4:
B b = (B) new A(); //编译通过,运行报错; 比较奇葩
test5:
B b = new B();
A a = (A)b;
a.f1; //调用B的f1
a.f2; // 调用B的f2
a.f3; //无法调用
继续实验加上一个C类继承自B,即B的子类, 提供方法f1,f3,f4
test6:
A a = new C();
a.f1; // 调用C中的 f1
a.f2; // 调用C的f2
a.f3; //
a.f4; //无法调用后2个
C c =(C)a;
c.f1; // C的f1
c.f2; // B的
c.f3; // C的
c.f4; //C的
test7:
C c = new C();
c.f1;
c.f2;
c.f3;
c.f4; //正常调用
A a = c;
a.f1; //C的f1
a.f2; //C的f2
a.f3;
a.f4; //后2个无法调用
test8:
C c = new C();
A a = (B)c;
a.f1;
a.f2; //C的f1, f2
a.f3;
a.f4; //后2个无法调用
其他的基本相同,逻辑差不多;
4, 父类A中的私有变量在子类B中的访问
class A {
private String s = "";
A(String ss) {
this.s = ss;
}
public String getS() {
return this.s;
}
}
public class B extends A {
private String s="";
B(String ss, String ss2) {
super(ss);
this.s = ss2;
}
public static void main(String[] args) {
B b = new B("123","456");
System.out.println(b.getS());
}
}
结果: 123
原因:父类的方法在子类中继承,实际是子类对父类方法的一个引用,如果子类中有方法(getS)覆写了父类中继承来的方法(getS), 那么结果是456;
5,构造函数和继承
- 当类没有声明构造函数的时候,编译器会自动生成一个无参构造函数,将所有实例成员设置成默认值;如果有构造函数就不会自动生成默认无参构造;
- 子类只继承父类的默认构造函数,即无形参构造函数。如果父类没有默认构造函数,那子类不能从父类继承到任何构造函数。
- 子类从父类处继承来的父类默认构造函数,不能成为子类的默认构造函数。
- 创建对象时,先调用父类默认构造函数对对象进行初始化,然后调用子类自身自己定义的构造函数。
extra:子类继承的时候,必须调用父类的构造函数;这时它会默认调用继承父类的无参构造函数;如果父类没有默认无参构造函数,那么只能在子类构造函数第一行加super(XXX)来调用显示调用父类构造函数;
6,关于继承的一些有用建议:
- 公共的operation或fields,放在父类中
- 不要使用protected的field
- 继承应用到“is-a”模型中
- 除非继承的方法有意义,否则别用继承
- 当覆盖一个方法的时候不要改变它预期的行为
- 利用多态性,而不是用类型信息来判断
- 不要过度使用反射
7, 构造函数的基本执行顺序 (无静态情况,静态最优先)
- 所有数据成员被初始化为默认值(0, false, or null).
- 按照声明顺序初始化 块 中的所有成员.
- 如果调用的构造函数第一行调用了另外一个构造函数,那么第二个构造函数执行.
- 调用的构造函数执行.
-- 反射
1,得到Class的几种途径
Class cl = e.getClass();
Class cl = Class.forName(className);
Class cl1 = Date.class; or Class cl2 = int.class;
注:比较两个Class类型相等 直接用==
2,创建对象
Class.newInstance() 调用默认构造函数
一些snippet:
1,Modifier.toString(m.getModifiers()) 得到修饰符
2,
{
String brackets = "";
while (cls.isArray()) { // 转化多维数组时
brackets += "[]";
cls = cls.getComponentType();
}
String full_name = cls.getName();
int pos = full_name.lastIndexOf('.');
if (pos != -1)
full_name = full_name.substring(pos + 1);
return full_name + brackets;
}
3,
注:getFields, getMethods, and getConstructors 得到public的,并且可以得到父类的public的method和field但是不能得到constructor;getDeclaredFields, getDeclaredMethods, and getDeclaredConstructors能得到本类中声明的所有的方法成员和构造函数;
-- 克隆对象
clone三部曲。
1 声明实现Cloneable接口。
2 调用super.clone拿到一个对象,如果父类的clone实现没有问题的话,在该对象的内存存储中,所有父类定义的field都已经clone好了,该类中的primitive和不可变类型引用也克隆好了,可变类型引用都是浅copy。
3 把浅copy的引用指向原型对象新的克隆体。
考虑一个类对clone的态度,有如下几种。
1 公开支持:好吧,按照clone三部曲实现吧。前提是父类支持(公开或者默默)。
2 默默支持:不实现Cloneable接口,但是在类里面有正确的protected的clone实现,这样,该类不支持clone,但是它的子类如果想支持的话也不妨碍。
3 不支持:好吧,为了明确该目的,提供一个抛CloneNotSupportedException 异常的protected的clone实现。
4 看情况支持:该类内部可以保存其他类的实例,如果其他类支持则该类支持,如果其他类不支持,该类没有办法,只有不支持。
-- 内部类
使用内部类的理由:
- 内部类能够访问定义它们的类中的数据,包括private的
- 同一包中的内部类能够被其他类(外部)给隐藏起来
- 当你想定义回调函数时,使用匿名内部类将非常方便,使你不用编写很多代码.
内部类持有外部类的引用,在内部类的默认构造函数中会创建一个到外部类的引用;
默认构造函数类似这样:
public Inner(Outer out) // automatically generated code
{
this.outer = out;
}
-- 代理
-- 容器类
1,数组和列表
数组大小确定后,内部自动赋值,但是list创建的时候指定大小,如果里面不存值便不占用存储空间:
int[] array = new int[100];
ArrayList<Integer> list = new ArrayList<Integer>(100);
array[50]=4; // 第50个元素设置为4
list.add(50,4); // fail, 目前list大小为0, 不能加入第50个item,要从头开始添加;
for(int a : array)
System.out.println(a); //第50个为4,其余为0
-- 其他
1.Eclipse 遇到错误提示“Failed to create the Java Virtual Machine ”
问题解决:
找到eclipse目录下的eclipse.ini 编辑这段:
--launcher.XXMaxPermSize
256M //也可能其他值 改成128M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m //也可能其他值 改成128M