J2SE之类之间的关系
继承
如果子类和父类在同一个包中,则子类继承了其父类中不是private的成员变量作为自己的成员变量,而且继承了父类中不是private的方法作为自己方法。如果子类和父类在不同的包中,那么子类将不会继承父类的友好变量和友好方法及不带权限标识的方法和成员变量,如果父类里的变量不是静态变量,当我们用new出一个子类对象,当我们用set方法改变实例变量的时候,改变父类的子类会变,改变子类的父类会变。如果new另一个子类则重新获得最原始的父类的实例变量。如果是静态的实例变量,父类的实例变量的改变,用任何子类访问的实例变量都改变!
接口和抽象类
声明方法的存在而不去实现它的类被叫做抽象类,它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。抽象类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。
在设计类的时候,可以结合抽象类和接口类在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现。就好比GUI里面设计了KeyListener和KeyAdapter。
静态
局部变量不能是静态。常量一般除了加final,通常也要加static。Static方法要通过类名访问。静态方法不能有非静态数据的引用。抽象方法不能加static和final。?接口中的变量只能是常量?
多态
Java多态存在的三个必要条件:
1.需要有继承关系的存在2.需要有方法的重写3.需要有父类的引用指向子类对象对于成员变量没有多态,只有方法有多态。多态的实现有两种,一种是是通过继承,一种是通过接口。多态就涉及到父类引用指向子类对象,我们只能用父类的引用来调用子类的重写方法,确不能调用子类的非重写的方法需要用到强制类型转换。In addition,对于重载而言,方法之间是否distinct,signature可以是参数的位置和参数的数量,不能依靠返回值和相同的参数类型但是不同的参数名字。
容器
Set接口和list接口继承了collection接口,Hashset类实施了set接口,LinkedList和ArrayList实施了List接口,HashMap实施了Map接口
Collection接口定义了存取一组对象的方法,其子接口set和list定义了储存方式 Set中的数据对象没有顺序且不可以重复(可以过滤掉相等)
List中的数据对象有顺序且可以重复
容器类对象在调用remove、contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashCode方法;对于自定义类型,需要重写equals和hashcode方法以实现自定义的对象相等规则,ps:相等的对象应该具有相等的hashcodes.增加Name类的equals和hashCode方法如下:
import java.util.*;
public class BasicContainer {
public static void main(String[] args) {
Collection c = new HashSet();
c.add("hello");
c.add(new Name("f1","l1"));
c.add(new Integer(100));
c.remove("hello");
c.remove(new Integer(100));
System.out.println
(c.remove(new Name("f1","l1")));
System.out.println(c);
}
}
class Name implements Comparable {
private String firstName,lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName; this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String toString() { return firstName + " " + lastName; }
public boolean equals(Object obj) {
if (obj instanceof Name) {
Name name = (Name) obj;
return (firstName.equals(name.firstName))
&& (lastName.equals(name.lastName));
}
return super.equals(obj);
}
public int hashCode() {
return firstName.hashCode();
}
public int compareTo(Object o) {
Name n = (Name)o;
int lastCmp =
lastName.compareTo(n.lastName);
return
(lastCmp!=0 ? lastCmp :
firstName.compareTo(n.firstName));
}
}
super只能用于不是static的方法
只能用super调用父类的protected方法
super(); // 调用父类构造函数
super(name);// 调用父类具有相同形参的构造函数
super.method();//当子类的方法覆盖了父类后,仍然想调用父类
super.a//实例变量也如此
System.out.println(a); 这里会自动去调用toString();
iterator
給了一個统一遍历的方法,因为一个是数组型,一个是元素指向型
对象实现了方法的一部分?
容器4那一章,iterator接口是怎样实现多态的?(返回了實現iterator的對象)
實現多态的三要素:重写,继承,父类的引用指向子类的对象
java.util.Collections 好多都是静态方法,需要用collection去访问
binarySearch()折半查找法
object
put(Object key,Object value)
Object是key前一个所指对象,注意返回类型是object类型,需要按要求强制类型
auto-boxing和unboxing可以在map里运用
只有当用到hashSet的时候才会用hashcode?
重写equals方法一定要重写hashcode方法
当从hashSet中访问元素时,hashSet先计算元素的hashCode值(也就是调用该对象的hashCode()方法的返回值)
String和object类都有hashcode()方法
先来看能表明hashcode和equals的关系的几句话:
equals()相等的两个对象,hashcode()一定相等;
equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。
反过来:
hashcode()不等,一定能推出equals()也不等;
hashcode()相等,equals()可能相等,也可能不等。
1136!一个图,一个内(collection)三个知识点(for,generic,auto-boxing)
六个接口
将Integer类型强制转换为String类型,无法通过。
将object转成String类型的值。使用这种方法时,需要注意的是类型必须能转成String类型。
因此最好用instanceof做个类型检查,以判断是否可以转换。否则容易抛出CalssCastException异常
进程是一个静态的概念,一个进程里有个主线程是main方法。
线程是一个进程里的不同的执行路径
每一个thread对象代表一个新的线程,两种方法创建新的线程
第一种 定义线程是实现的runnable借口
第二种
可以定义一个Thread的子类并重写其run方法
用第一种方法 更灵活
重写方法不能抛出比被重写方法不同的异常
run方法一结束线程就结束
synchonized执行这个方法的过程中当前对象被锁定
死锁?
解锁的办法把锁的粒度加粗
改要加synchonized,读不用加
wait方法的当前对象的锁不再归其所有,而sleep方法任然归其所有
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,
当第一个线程运行完毕以后释放对象上的锁,此时如果该对象没有再次使用notify语句,
即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,
继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
写程序先关心有哪些个类,那些个对象,每个类里有哪些个方法
子网掩码?网关?TCP可靠但是慢,UDP不可靠但是快
端口号(port number)来保证的是别人qq上发的信息不至于发到你的msn上占两个字节
TCP和UDP的端口不是一回事,相同數字表達的是不同端口
阻塞似的,傻傻的等着
接口来组织整个类的结构
缓冲流要套接在相应的节点流之上,对读写数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
转换流是把字节流转换成字符流(非常有用)
ajax和javascript完全替代了applet
泛型的起因装入集合的类型都被当做object对待,从而失去自己的实际类型,从集合中取出时往往需要转换,效率低且往往产生错误
如果放其他类型的对象进数组的话报错就会发生在编译的时期,强制类型转换的话就会报错在运行期,报错越提前越好
比如List c=new
ArrayList();
c.add("aaa");
c.add("bbb");
c.add("ccc");
当去遍历数组的时候如果不用泛型需要强制类型转换
String s=c.get(i);
能使用继承frame,就不要直接new一个frame对象,因为继承后的类能随自己意愿创造成员变量
事件和监听某件事实现的接口是一一对应的
facade模式?
每个component都有一个paint(Graphics g)用于实现绘图目的,每次重画Component时都自动调用paint方法
当graphics调用drawline时,由于是drawline方法是抽象类,则graphics子类实现了抽象类这一方法
双缓冲? repaint update paint
当frame从画的的时候paint就会被调用
Thread提供了让一个线程等待另一个线程完成的方法join();当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()放大加入的join()线程执行完为止
双缓冲:
Image offScreenImage = null;
if (offScreenImage == null)
offScreenImage =
createImage(BLOCK_SIZE * COLS, BLOCK_SIZE * ROWS);
Graphics gOff =
offScreenImage.getGraphics();
//
4.调用paint(),将缓冲图象的画笔传入
paint(gOff);
//
5.再将此缓冲图像一次性绘到代表屏幕的Graphics对象,即该方法传入的“g”上
g.drawImage(offScreenImage, 0, 0,
null);
作为一个内部类首先你要new一个外部的对象才能new内部的对象
贪吃蛇:当Yard的对象建立后程序显示窗口(Frame extends
component)程序首先自动调用重载后的paint函数,在窗口绘制一个小圆,绘图线程启动后,
该线程每隔100ms修改一下蛇的位置,然后调用repain()函数,这个repaint()函数并不是我们重载的,而是从Frame继承过来的,它先调用update函数,update
再调用paint()函数
1、当父类中有默认的构造函数时,子类自动调用父类的构造方法;2、当父类中有带参数的构造函数时,子类需要使用super关键字调用父类的构造函数,而且必须放在子类构造方法的第一句。
抽象方法与抽象的行为相对应,通常是这个行为对父对象没有意义,而子对象有具体动作
抽象类可以有抽象方法也可以没有抽象方法;但是如果一个类有抽象方法,那这个类只能定义为抽象类
(1)抽象类可以有实例变量,而接口不能拥有实例变量,接口中的变量都是静态(static)的常量(final)。
(2)抽象类可以有非抽象方法,而接口只能有抽象方法。
接口中不能有实例变量,只能有静态的常量,不能有具体的方法(包含方法体),只能有抽象方法,因此也就摒弃了多继承的缺点。
对于一个类实现多个接口的情况,因为接口只有抽象方法,具体方法只能由实现接口的类实现,在调用的时候始终只会调用实现类的方法(不存在歧义),因此不存
在多继承的第二个缺点;而又因为接口只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变
量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。
对于一个接口继承多个父接口的情况也一样不存在这些缺点。
请看以下示例。
接口A:
Java代码
public interface InterfaceA
{
int len = 1 ;
void
output();
}
接口B:
Java代码
public interface InterfaceB
{
int len
= 2 ;
void
output();
}
接口InterfaceSub继承接口A和接口B:
Java代码
public interface InterfaceSub extends
InterfaceA, interfaceB
{
}
类Xyz实现接口InterfaceSub:
Java代码
public class Xyz implements
InterfaceSub {
public void
output() {
System.out.println( "output in class Xyz." );
}
public
void outputLen( int type) {
switch (type) {
case InterfaceA.len:
System.out.println( "len of InterfaceA=." +type);
break ;
case InterfaceB.len:
System.out.println( "len of InterfaceB=." +type);
break ;
}
}
public static void main(String[] args)
{
Xyz xyz= new Xyz ();
xyz .output();
xyz .outputLen();
}
以上代码不存在什么问题,但是如果试图编写以下存在冲突的代码,则会编译失败。
Java代码
Xyz xyz = new Xyz();
int len
= xyz.len;
System.out.println(len);
打印流自动flush,且不用trycatch,printWriter
原文:http://www.cnblogs.com/fred-zhang/p/3555815.html