接口(interface)
(1)接口的由来:当一个类中所有的方法都是抽象的时候,你没必要定义为抽象类,
定义为接口就可以了。
(2)解决了java中只能单继承的问题。(对多继承进行了优化)
A:类与类:只能是单继承。 extends
B:接口与接口:可以是单继承,也可以是多继承。 extends
C:类与接口:可以是单实现,也可以是多实现。 implements
(3)成员特点:
A:只有成员变量和成员方法。
B:成员变量 默认修饰符 public static final
**int X = 20;
**其实是这样的 public static final int X = 20;
C:成员方法 默认修饰符 public abstract
**void show();
**其实是这样的 public abstract void show();
建议:为了便于阅读,自己手动加上修饰符。
(4)接口特点:
A:接口是对外暴露的规则
B:接口是功能的扩展
C:接口降低了程序的耦合性。
**内聚(自己实现功能的能力)
**高内聚,低耦合。
举例:主板和CPU,USB接口,电源插座。
D:扩展说了下接口的理解
**狭义的理解就是java中的接口。
**广义的理解就是:任何定义的规范都是接口。
(5)接口和抽象类的区别:
A:抽象类只能被单继承;接口可以被多实现。
B:抽象类中的成员:成员变量:可以是常量,也可以是变量。
成员方法:可以是抽象的,也可以是非抽象的。
构造方法:虽然不可以创建对象,但是可以给子类实例化用。
接口中的成员:成员变量:只能是常量。默认修饰符 public static final
成员方法:只能是抽象的。默认修饰符 public abstract
C:抽象类中定义的是体系结构中的共性的内容。
接口中定义的是对象的扩展功能。
D:抽象类被继承表示的是:"is a"的关系。xx是yy中的一种。
接口被实现表示的是: "like a"的关系。xx像yy中的一种。
多态
(1)某一类事物的多种存在形态。
**方法重载(静态多态)
**方法重写(动态多态,对象多态)
(2)对象多态的前提
A:类与类(或接口)要有继承(或实现)关系。
B:一定要有方法的重写。
C:一定要有父类或者接口的引用指向子类的对象。
(3)多态思想:可以指挥同一类型的一批对象做事情。多态的出现让我们复杂的问题简单化了。
(4)多态中成员的特点:(我们只研究特殊的,就是说名字一样的东西)
Fu f = new Zi();
A:成员变量:编译和运行都看Fu。
B:非静态方法:编译看Fu,运行看Zi。
C:静态方法:编译和运行都看Fu。
总结:无论是向上转型还是向下转型,变化的都是子类对象,绝对不能把父类对象强转为子类类型
内部类
内部类分别有:1,非静态成员内部类2,静态成员内部类3,局部内部类4,匿名内部类
(1)成员内部类
A:定义,:在一个外部类中有成员变量和成员方法,那么成员内部类就是把整个一个类当成了外部类的成员对待了
B: 访问方式:内部类访问外部类,内部类可以直接访问外部类,包括私有成员,因为内部类拥有外部类的引用是类名.this
外部类访问内部类,外部类访问外部类的成员,必须要建立内部类的对象
格式:外部类名.内部类名 = 外部类对象.内部类对象;
C:存放位置:在外部类里,在外部类的成员方法外.
D:修饰符:final、abstract、public、private、protected和static等,那么被static修饰的就是下面所说的
静态内部类.
(2)静态内部类
A:定义,就是在成员内部类的基础上加上static
B:格式:外部类名.内部类名 = 外部类名.内部类对象;
C:存放位置:和成员内部类一样,就是多了个static
(3)局部内部类
A:定义,在外部类成员方法中定义的内部类,他更像局部变量
B: 注意:
第一:方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
第二:方法内部类对象不能使用该内部类所在方法的非final局部变量。因为方法的局部变量位于栈上,
只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。
但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!
例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。
正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
第三:方法内部类的修饰符。与成员内部类不同,方法内部类更像一个局部变量。可以用于修饰方法内部类
的只有final和abstract。
第四:静态方法内的方法内部类。静态方法是没有this引用的,因此在静态方法内的内部类遭受同样的待遇,
即:只能访问外部类的静态成员。
(4)匿名内部类:没有名字的内部类。它是内部类的简化写法。
A:前提:内部类可以继承或实现一个外部类或者接口。
B:格式为:new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
C:简单理解:就是建立一个带内容的外部类或者接口的子类的匿名对象。
D: a,继承式的匿名内部类
b,接口式(也可以叫实现式的,名字无所谓)的匿名内部类
c,参数式的匿名内部类
多加一句:我的理解,其实与其说是匿名内部类,我个人认为说是匿名对象更确切一点(个人理解,仅供参考);
(5)什么时候使用匿名内部类呢?
A:通常在使用方法是接口类型参数,并该接口中的方法不超过三个时,
可以将匿名内部类作为参数传递。
2:异常
(1)就是程序运行过程中,遇到了问题,这就叫异常。
(2)异常的体系
Throwable 其实应该分三种
Error
通常出现重大问题如:运行的类不存在或者内存溢出等。
不编写针对代码对其处理。
Exception
除了 RuntimeException 和其所有子类,其他所有的异常类都是在编译的时候必须要处理的
要么try,要么抛
RuntimeException
RuntimeException 和其所有的子类,都不会在编译的时候报异常,而是在运行时报异常,这时候我们
就需要回头看看我们的代码是否有问题,比如角标越界,空指针等
(3)Throwable Runnable
A:getMessage() :返回此 throwable 的详细消息字符串。
B:toString():获取异常类名和异常信息,返回字符串。
C:printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
(4)处理异常处理方式:
A:try...catch...finally
格式:
try {
需要检测的代码;
}
catch(异常类 变量) {
异常处理代码;
}
...
finally {
一定会执行的代码;
}
可以有下面三种搭配形式:
**try...catch(...)
**try...finally
**try...catch(...)...finally
B:抛出 throws throw
throws:用于标识函数暴露出的异常。thorws用在函数上,后面跟异常类名(可以由多个,隔开)。
throw:用于抛出异常对象。throw用在函数内,后面跟异常对象。new Exception();
C:到底用谁?
**你能处理,建议处理。try...catch...finally
**你处理不了,抛出。
**在实际开发中,是分层开发,底层代码是能抛出尽量抛出,到顶层的是会把一些不友好的异常转换成友好的异常
用日志记录住异常信息,并提供解决方案
D:自定义异常
自定义类继承Exception或者其子类(RuntimeException)
E:RuntimeException和Exception
区别:RuntimeException就是要你改代码的。你可以不处理。
包
(1)包:package
A:对类文件进行分类管理
B:给类提供多层命名空间
C:放在程序代码的第一行(注释除外)
(2)访问:先得有包,然后:包.类名
如何解决手动创建包的问题呢?
javac -d xxx PackageDemo.java
-d 后面跟的是:目录
当前目录:.
(3)不同包之间类的访问
类一定要用全路径名称:包名.类名
protected
包之间的继承关系。
import
简化类名。
一个程序文件中只有一个package,可以有多个import。
用来导包中的类,不导入包中的包。
通常写import mypack.Demo;
而不写import mypack.*;为什么?
权限修饰符
同一个类中 同一个包中 不同包中子类中 不同包中,不存在继承关系
private OK
默认 OK Ok
protected Ok Ok Ok
public OK Ok OK OK
特殊:private和static可以修饰内部类。
static可以代码块。静态代码块。
A:四种访问权限修饰符任意时刻只能使用一种。
B:static,private,final 不能和abstract并用。
jar
(1)打包:
jar -cf haha.jar packa
(2)查看jar包
jar -xvf haha.jar
(3)如果内容特别多,好几个屏幕都放不下,
我们能够通过dos命令,讲这些目录写入到一个记事本中。数据重定向。dos的命令
jar -tf haha.jar > c:\a.txt
多线程
(1)多线程
进程:
线程:
单线程:
多线程:
(2)如何实现多线程呢?
A:继承Thread类
步骤:
**定义一个类,继承Thread类
**重写run方法
**调用start方法.
**启动线程
**调用run方法
Thread类中的常用方法:
**Thread(String name):通过构造给线程起名字
**setName(String name):通过set方法给线程起名字
**getName():获取线程的名称
**currentThread():获取当前线程的一个对象引用
***获取哪些没有直接继续Thread类的线程名称
B:实现Runnable接口
步骤:
**定义一个类,实现Runnable接口
**重写run方法
**创建实现了Runnable接口的子类对象,并把该对象作为参数传递给
Thread类的对象.这个时候,调用Thread类的start方法.
(3)线程的状态
A:被创建
B:运行
C:临时阻塞
D:冻结:sleep,wait导致阻塞
sleep的时间到了,wait的被唤醒了.就到了就绪状态
E:消亡
(4)卖票的问题
A:继承Thread实现卖票
这个时候,我们的票需要定义为静态的.但是呢,我们不建议这样做.
1,静态生命周期长
2,java是单继承,继承了Thread后就不能继承别的类,如果能有接口实现岂不是更好
B:实现Runnable接口卖票
在这里,我们就发现卖票除了问题.(线程安全问题)
线程安全问题怎么产生的?
**多个线程延迟访问
**线程的随机性
(5)解决线程安全问题
A:同步代码块
格式: synchronized(对象)
{
//被同步的代码,也就是可能出现安全问题的代码
}
B:同步方法
就是在方法上加synchronized关键字即可.
C:同步的前提:
**同步需要两个或者两个以上的线程
**多个线程使用的是同一个锁。
未满足这两个条件,不能称其为同步。
D:同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,
无形中会降低程序的运行效率。