设计模式
设计模式有23种,所有面向对象的语言都有这23种设计模式。
单例设计模式
单例:单个实例(对象)
步骤:
1.Test不能让别人创建对象 ---》Test构造方法变成私有的 (Test类不让创建对象了)
2.Test类自已创建自已的对象 (别人拿不了,因为Test不让创建对象,不能通过对象名.属性拿)
3.Test类对外提供一个公共的静态方法,让别人拿这个对象 (静态方法不能调用非静态变量)
4.Test类把这个对象变成静态变量
5.拿对象----》类名.方法名()
6.拿的对象是同一对象,指向的是同一内存地址。
保证对象唯一性思想:
1)不允许其它程序用new来创建对象
2)在该类创建一个本类实例
3)对外提供一个方法,让其它程序可以获取该对象
什么是继承?
多个类中存在相同属性和行为时,将这些相同的内容拿出来放在一个单独类中,那么多个类无需再定
义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。继承
的出现提高了代码的复用性。
什么时定义继承?
xx是yy的一种 ---- xx is a yy
继承后子类中成员的特点
成员(全局)变量特点:
1)重名 子类属性 this.XX 父类:super.XX
2)不重名 XX XXX
成员方法特点:
1)不重名
2)重名 ----重写(覆盖,复写 overide)
重写:在子父类中,如果子类中的方法和父类中的方法同名,相同返回值,参数列表也相同,并
且访问权限>=父类中的方法,子类中的方法覆盖父类中的方法
构造方法特点:
1)子类的构造方法自动在第一行调用了父类默认的构造方法 super();
2)当父类默认的构造方法消失时,子类会报错,子类的构造方法要手动在第一行添加父类自定义的
构造方法。
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量,只能被赋值一次。
内部类只能访问被final修饰的局部变量。
抽象什么时用
当类里有的方法在描述事务时,不具体,无法准确的描述,这时,我们就可以用抽象来解决这个问题
抽象特点
1.抽象类不可以被实例化,也就是不可以用new创建对象。
2.抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子
类也是抽象类。
3.抽象类是由abstract来修饰的。
4.抽象类中可以有抽象方法,也可以没有,可以有普通方法也可以没有。
抽象方法和普通方法的区别
1)抽象方法只有方法头,没有方法体。普通方法都有
2)抽象方法由abstract来修饰,普通方法没有
3)抽象方法必须活在抽象类中,普通方法既可以活在抽象类中也可以活在非抽象类中
抽象类和普通类的异同
相同点:
抽象类和普通类都是用来描述事务的,都在内部定义了成员(方法和属性)。
不同点:
普通类有足够信息来描述事务,抽象类描述事务的信息有可能不够充足
普通类不能定义抽象方法,只能定义普通方法,抽象类中可以定义抽象方法,同时也可以定义普通
方法
普通类可以被实例化,抽象类不可以被实例化(创建对象)
抽象关键字abstrat不可以和private,static,final关键字共存。
接口
类中的方法都是抽象时,这个类就叫作接口。
接口就是特殊的抽象类,即所有方法都是抽象方法的抽象类就是Java中的接口(interface)
接口如何创建
[修饰符] interface 接口名{
[public] [static] [final] 数据类型 变量名;
[public] [abstract] 返回值 方法();
}
接口中的成员修饰符是固定的
public static final修饰的变量变为常量,该值不能改变,只能读
修饰符:可选,用于指定借口的访问权限,可选值为public.即使省略也依然是public.
接口名:必选参数,用于指定接口名称,接口名必须是合法的java标识符。一般情况下,要求首字母大
写。
方法:接口中的方法只有定义而没有被实现。
类与接口之间是实现关系
接口不可以被实例化,实现了接口的子类并且覆盖接口中所有抽象方法后,这个子类才可以被实例化,
否则这个子类就是一个抽象类。
java不支持多继承,java将多继承机制进行改良变成了多实现
一个类可以实现多个接口;一个类若实现了多个接口,必须把多个接口中的方法全部实现。
接口与接口之间是继承关系,而且可以多继承。接口的出现避免了单继承的局限性。
接口与抽象类的关系
共性:都是不断抽取出来的抽象的概念
区别1:抽象类体现继承关系,一个类只能单继承;接口体现实现关系,一个类可以多实现
区别2:抽象类是继承 是is a关系(所属关系) 在定义该体系的基本共性内容;接口是实现 是
like a关系(不所属关系) 在定义该体系的额外功能
区别3:抽象类中可以定义非抽象方法,供子类直接使用;接口的方法都是抽象,接口中的成员都有固定
修饰符
什么是多态
多态:字面上理解,多种形态
方法有多种形态:方法的重写,方法的重载
对象的多种形态
多态语法:
父类类名 对象名 = new 子类类名()
Animal cat = new Cat();
多态前提
1)类之前要有继承关系
2)方法要有重写
多态的特征
在多态情况下:
1)子父类中都有同名静态方法时,调用同名静态方法应该注意:
编译看左边,运行看左边
2)子父类中都有同名非静态方法时,调用同名非静态方法应该注意:
编译看左边,运行看右边
3)子父类中都有同名属性(静态和非静态)时,调用同名属性(静态和非静态)应该注意:
编译看左边,运行看左边(因为:变量是不存在覆盖的,只有方法才能覆盖)。
多态的好处:提高代码复用性,便于维护。
多态的缺点:多态后,不能调用子类特有的(只有子类中有,父类中没有的方法)方法。
多态的缺点的解决方法
向上转型(上塑造型):Animal an = new Cat();
向下转型(下塑造型):Cat cat = (Cat)an;
向下转型注意:Animal an = new Cat();
Dog dog =(Dog)an; 错误的
Animal an = new Animal();
Dog dog =(Dog)an; 错误的
如:猫是动物的一种,动物不单单是猫。
多态类型的判断instanceof
对象 instanceof 类 --------》结果是 boolean
什么是内部类:类里面定义的类
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)
定义的位置:定义在成员位置上、定义在局部位置上(方法、代码块)、匿名内部类(new A()
{...}.show();)
内部类访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
内部类的好处:为了访问方便。
异常:字面上理解,不正常的情况。指程序运行中遇到的非致命的,通过某种修正后还能继续执行的错
误
异常分类:
IOException: 编译异常
RuntimeException:运行异常
常见的运行异常:算数异常ArithmeticException;数组下标越界ArrayIndexOutOfBoundsException;类型
转换异常ClassCastException;创建一个长度为负数的数组NegativeArraySizeException;空指针异常
NullPointerException
常见的编译异常:输入输出异常IOException;未找到文件异常FileNotFoundException;指示在底层协议
中存在错误,如 TCP 错误SocketException;指定名字的类或接口未找到ClassNotFoundException
异常处理:
try{ }catch(异常类 异常对象){ }finally{ }
try{ }catch(异常类 异常对象){ }
try{ }finally{ }
getMessage():用来提供有关异常事件的信息;
printStackTrace():异常名称、信息、位置。包括getMessage()的内容;
toString():得到异常类名和相关信息;
finally:为异常处理提供统一出口,对程序进行统一管理,无论try中有没有抛出异常,finally都被执
行;一般用于资源的清理和释放工作。如:关闭已打开的文件、删除临时文件、释放数据库连接;
使用方式:异常对象.getMessage()
throw和throws的区别
throws什么时用:在方法头抛异常,可以抛多个,用逗号分隔
throw什么用:在方法内部用,抛的是异常的对象,只能抛一个
throw 运行期异常对象()---->方法头部不用必须throws
throw 编译期异常对象()---->方法头部必须throws,有几个抛几个
异常与继承之间的关系
当方法抛出异常时,子类如何重写:
1)子类方法可以不抛
2)子类抛和父类方法抛出的异常相同
3)子类抛父类方法抛出的异常的子类异常
自定义异常:
Class MyException extends Exception{
MyException(){//无参构造方法
super();//实际都是由父类来完成这个功能的
}
MyException(String s){//有参构造方法
super(s);//实际都是由父类来完成这个功能的
}
}
finally 在什么情况下才不被执行
1)当try中没有异常时如果加了System.exit(1);--->(退出虚拟机的方法)
2)当try中有异常时,在catch中如果加了System.exit(1);--->(退出虚拟机的方法)
java常用包介绍:
java.lang 核心类库 数据类型 数学类 字符串 线程
java.util 日期类 时间 堆栈 Vector 向量
java.io 提供对文件进行操作的类File 输入流 输出流
java.net 实现网络功能
java.applet java小程序
集合作用:可以装对象(任何对象)
问:数组装对象和集合装对象的区别?
答:数组一创建就给定大小,数组存放的元素类型是同一类型。
集合创建不用定大小,集合存放的元素类型是Object.
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型和引用
数据类型,集合只能存储对象。
Collection接口有两个子接口。List(列表),set(集).
List:可存放重复元素,元素存取是有序的。元素都有下标,元素可以重复。
Set:不可以存放重复元素,元素存取是无序的。元素没有下标,元素不可以重复。
Collection接口:
1.添加 boolean add(Object obj);
boolean addAll(Collection c)
2.删除:
boolean remove(Object o)
boolean removeAll(Collection c)
void clear()
3.判断:
boolean isEmpty()
boolean contains(Object o)
boolean containsAll(Collection c)
4.获取:
int size() //长度
5.其它
Object[] toArray()
List接口:
1.添加:
void add(int index, E element)
boolean addAll(int index, Collection c)
2.删除
Object remove(int index)
3.修改:
Object set(int index, E element)
4.获取:
Object get(int index)
int indexOf(Object o)
int lastIndexOf(Object o)
List subList(int fromIndex, int toIndex)
从集合中取值的方式:
List col=new ArrayList();
col.add("123");
col.add("456");
col.add("789");
col.add("123");
col.add(new Person());
1)
for(int i=0;i<col.size();i++){
System.out.println(col.get(i));
}
2)
Iterator it = col.iterator();//迭代器
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str); //注意如果都是String类型这样才可以强转
}
3)
for(Iterator its = col.iterator();its.hasNext();){
System.out.println(its.next());
}
泛型:
Ren ren1 = new Ren("pengpeng",1);//
Ren ren2 = new Ren("dongdong",1);
List<Ren> col=new ArrayList<Ren>();//泛型
col.add(ren1);
col.add(ren2);
Iterator<Ren> it = col.iterator();
while(it.hasNext()){
Ren ren = it.next();
System.out.println(ren.getAge()+","+ren.getName());
}
作用:1)可以规定集合存放元素的类型
2)取值时不用强转
LinkedList和ArrayList的区别?
LinkedList: 增加 删除快,查询慢
ArrayList:增加 删除慢,查询快
Vector(向量)
Vector:
Ren ren1 = new Ren("pengpeng",1);
Ren ren2 = new Ren("dongdong",2);
Vector<Ren> co=new Vector<Ren> ();
co.add(ren1);
co.add(ren2);
Enumeration<Ren> en = co.elements(); //---->枚举
while(en.hasMoreElements()){
Ren ren = en.nextElement();
System.out.println(ren.getName()+","+ren.getAge());
}