工厂设计模式:
java中使用的最多的一种设计模式,在接口与具体子类直接加一个过渡。
工厂模式在《Java与模式》中分为三类:1. 简单工厂模式(Simple Factory):不利于产生系列产品;
2. 工厂方法模式(Factory Method):又称为多形性工厂;
3. 抽象工厂模式(Abstract Factory):又称为工具箱,产生产品族,但不利于产生新的产品;
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
在这里由于知识有限暂时只介绍简单工厂模式,另外两个类型我会有空时放到博客里专门开一篇来讲,也可以见更多文章。
例:
public class FactoryModel
{
public static void main(String[] args)
{
Fruitf = null;
f= Factory.get("橘子");
f.eat();
}
}
interface Fruit
{
public void eat();
}
class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
class Factory//工厂类
{
public static Fruit get(String name)
{
Fruitf = null;
if("苹果".equals(name))//这里不能把name写在前面,否者会出现空指针异常
{
f= new Apple();
}
if("橘子".equals(name))
{
f= new Orange();
}
return f;
}
}
学完反射后,还可以优化工厂类的写法。
代理设计模式:
就是真实功能与客户端之间加入了一个代理,处理其他业务。比如,游戏开发商和游戏代理商,开发商是具体实现游戏的功能,代理商则负责推销,出售。
例:
public class AgencyGameDemo
{
public static void main(String[] args)
{
Agencyp = new Agency(new RealGame(),10);
p.browse();
}
}
interface Game
{
public void browse();
}
class RealGame implements Game//真真实现功能的类
{
public void browse()
{
System.out.println("游戏启动成功!");
}
}
class Agency implements Game//代理类,代理类可以实现更多的功能,这里判断游戏是否有余额来启动游戏。
{
private Game net;
private int money;
public Agency(Game net,int money)
{
this.net = net;
this.money=money;
}
public boolean check()
{
if (money>0) {
return true;
}else {
return false;
}
}
public void browse()
{
if (this.check()) {
this.net.browse();
System.out.println("您的余额还剩:"+this.money+"元");
}
else {
System.out.println("您的金钱不足,无法开启游戏!");
}
}
}
适配器设计模式:
适配器模式:将一个类的接口转换成客户希望的另外一个接口。
使用场景:
1. 已经存在的类的接口不符合我们的需求;
2. 创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;
3. 在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类
实现的方法:
1. 类的适配器模式(采用继承实现)
例:
public class AdapterDemo {
public static void main(String[] args) {
Target normal = new Normal();
normal.method();//调用普通功能类
Target adapter = new Adapter();
adapter.method();//使用特殊功能类,即适配类
}
}
interface Target {//目标接口
public void method();
}
//已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Special {
public void speciallyFunction() {
System.out.println("适配器类具有特殊功能");
}
}
// 具体目标类,只提供普通功能
class Normal implements Target {
public void method() {
System.out.println("普通类具有普通功能");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Special implements Target{
public void method() {
super.speciallyFunction();
}
}
2.对象适配器(采用类中传入对象)
例:
public class AdapterDemo {
public static void main(String[] args) {
Target normal = new Normal();
normal.method();//调用普通功能类
Target adapter = new Adapter(new Special());
adapter.method();//使用特殊功能类,即适配类
}
}
interface Target {//目标接口
public void method();
}
//已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Special {
public void speciallyFunction() {
System.out.println("适配器类具有特殊功能");
}
}
// 具体目标类,只提供普通功能
class Normal implements Target {
public void method() {
System.out.println("普通类具有普通功能");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter implements Target{
private Special special;
public Adapter(Special special) {
this.special = special;
}
public void method() {
this.special.speciallyFunction();
}
}
内部类:
1.普通内部类:
把一个类定义在另外一个类的里面,里面那个就称为内部类。
访问特点: 内部类可以直接访问外部类中的成员,包括私有成员。外部类要访问内部类中的成员必须建立内部类的对象。
扩展:
接口里边可以定义内部接口和抽象类
抽象类里也可以定义接口和抽象类
例:
public class InnerDemo
{
public static void main(String[] args)
{
new Outer().getInner().print();
}
}
class Outer
{
private String name = "java";
class Inner
{
public void print(){
System.out.println(name);
}
}
public Inner getInner(){//外部访问内部类需要创建对象
Innerin = new Inner();
return in;
}
}
2.static定义内部类:
使用static定义内部类是,可以直接调用,不用创建对象。
例:
public class InnerDemo
{
public static void main(String[] args)
{
new Outer.Inner().print();
}
}
class Outer
{
private static String name = "java";//这里也必须是静态的,因为里面的静态类要访问这里的成员变量。
static class Inner
{
public void print(){
System.out.println(name);
}
}
}
3.方法中内部类:
将内部写在方法中,又想要访问方法中的参数,那么参数必须是final定义的(jdk1.8就可以不写final)
public class Singleton {
public static void main(String[] args) {
new Outer().fun(1); //传入参数给temp
}
}
class Outer{
public void fun(final int temp){
class Inner{
public void print(){
System.out.println("方法中的参数"+temp);
}
}
new Inner().print();
}
}
4.匿名内部类:
内部类可以继承或实现一个外部类或者接口。
例:
public class InnerDemo
{
public static void main(String[] args)
{
new Test().function().method();
}
}
interface Inner{
void method();
}
class Test
{
public Inner function(){
return new Inner() {
public void method() {
System.out.println("java");
}
};
}
}
匿名内部类其实就是内部类的简写格式。
Object介绍:
1. Object是所有对象的父类。
2. 它可以接受任何对象。
3. 它里面的equals方法是比较两个对象的地址值,如果相同返回true,否则返回false。
4. Object里面的toString方法和String里面的toString的方法不同,Object中的方法是返回对象所属的类名+@+该对象的哈希吗,而String中的方法重写了Object中的方法,是用于比较两个字符串内容是否相同。
包装类:
为了体现java中一切皆对象的理念,连基本数据类型也没有逃过变成对象的命运。
就是把原来的数据类型封装成对象,并添加了一些方法。
基本数据类型 | 包装类 |
int | Integer |
char | Character |
short | Short |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
byte | Byte |
封装以后就可以更方便的使用,里面自带了一些功能,比如MAX_VALUE显示该类型能够表示的最大值,当然也有MIN_VALUE。
拆箱和装箱:
装箱:把基本数据类型变成包装类
intx=1;
Integery = new Integer(x);
拆箱:将一个包装类变成基本数据类型
inttemp = y.intValue();
jdk1.5以后就可以自动拆箱和装箱:
intx=1;
Integery=x;
一般包装类是将前台输入的字符串数据转换成数字:
Stringstr1 = “11”;
Stringstr1 = “1.1”;
intx =Integer.parseInt(str1);
floatf =Float.parseFloat(str2);
异常:
异常是对问题的描述,将问题进行对象的封装。
异常就是导致程序终止的一种指令流,异常会使程序终止执行。
异常不是错误(Error),错误一般是出现重大问题如:运行的类不存在或者内存溢出等。不编写针对代码对其处理
异常体系:
java.lang.Object
┗━━java.lang.Throwable
┗━━Error
┗━━Exception
Exception和Error的子类名都是以父类名作为后缀。
异常体系中的所有类以及建立的对象都可抛性(也就是可以被throw和throws关键件操作)。
Throwable中的方法
public class ExceptionDemo {
public static void main(String[] args) {
try {
int[] a=new int[3];
System.out.println(a[3]);
}catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage()+",");
System.out.println(e.toString()+"。");
e.printStackTrace();
}
}
}
结果:
3,
java.lang.ArrayIndexOutOfBoundsException: 3。
java.lang.ArrayIndexOutOfBoundsException: 3
atExceptionDemo.main(ExceptionDemo.java:5)
getMessage() 获取异常信息,返回字符串。
toString() 获取异常类名和异常信息,返回字符串。
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void。
throws和throw的区别:
throws用在函数上,后面跟异常类名,用于抛出异常类,抛出多个用,隔开。
throw用在函数内,后面跟异常对象,用于抛出异常对象。
注意:RuntimeException除外。如果函数内抛出的RuntimeException异常,函数上可以不用声明。如果函数生命了异常,调用的时候就要进行处理,可以throws和try(如果在main里面,不建议抛出(throws)给虚拟机),也就是谁调用谁处理!。
异常处理流程:
try {
放入需要检测的代码
} catch (Exception e) {
异常代码处理,一个检测的代码(try)可以有多个catch处理
}
finally{
里面写的一定会被执行(除了System.exit(0),这是关闭虚拟机,虚拟机都关了,肯定执行不了了),通常写关闭资源代码。因为资源必须释放。
}
自定义异常:
自定义类继承了Exception或者它的子类。
通过构造函数自定义异常信息。
用throw把自定义的异常抛出。
例:
public class ExceptionDemo {
public static void main(String[] args) {
Divisiondi = new Division();
try {
System.out.println(di.div(5, -4));
}catch (MinusException e) {
// TODO Auto-generated catch block
System.out.println(e.toString());// 异常时输出此对象的类和name: 传入的值
}
}
}
class MinusException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;// 为了提高兼容性的序列化,可以忽略
private String message;
MinusException(Stringmessage) {
this.message = message;
}
@Override
public String getMessage() {
// TODO Auto-generated method stub
return message;// 重写异常中的getMessage方法,返回自己传入的值
}
}
class Division {
int div(int a, int b) throws MinusException {
if (b < 0) {
throw new MinusException("除数出现负数了");// 手动抛出自定义异常
}
return a / b;
}
}
异常细节注意:
1.RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
2.一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
3.如果父类抛出多个异常,那么覆写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。
包:
1. 对类文件进行分类管理。
2. 给类提供多层命名空间。
3. 写在程序文件的第一行。
4. 类名的全称是 报名.类名。
5. 包也是一种封装形式,把class文件和源文件分离,方便管理。
6. 编译时命令 javac –d 目标目录(当前目录为.) Demo.java
7. 父类和之类在不同包中,那么父类中的default和private方法都不能被子类继承。
包之间的访问:
1. 被访问的包中的类权限必须是public。
2. 包中类的权限被放大了,包中的方法也需要放大才能访问,public或protected。
3. protected是为其他包中的子类提供的一种权限。
improt:
当我们使用到其他包中的class的方法时,需要导入它的包名.类名。
简化类名。
import java.util.*可以导入util中所有的class,但是不推荐这样写,通常写为import java.util.Arrays,可以更清晰的阅读,知道导入的具体是什么。
Java中默认导入import java.lang
Java四种权限:
| public | protected | dafault | private |
同一类中 | √ | √ | √ | √ |
同一包中 | √ | √ | √ |
|
子类(不同包) | √ | √ |
|
|
不同包中无继承关系的类 | √ |
|
|
|
jar包:
别人做好了一些功能,把这些功能相关的class文件打成一个包,就是jar包,引入这个jar包,那就可以直接使用功能。
jar包特点:
1. 方便项目携带,相当于一种压缩格式。
2. 方便使用,在classpath设置jar路径即可。
jar包操作:
1. 创建jar包: jar –cvf test.jar packa packb
2. 查看jar包: jar –tvf test.jar (一般直接用rar压缩文件打开)
3. 解压jar包: jar –xvf test.jar (rar直接解压)
4. 自定义jar包的清单文件:jar –cvfm test.jar aa.txt packa packb
5. 访问jar时注意设置classpath: set classpath=.\;d:\test.jar