java中有23中设计模式,其中单例模式能解决一个类在内存中只有一个对。
单例模式的两种方式:
1、饿汉式
eg:
class Single
{
private Single(){}//将构造函数自由化防止创建新对象
private static Single s=new Single();//为了满足下面getInstance是静态的所以要将其静态化
private static Single getInstance(){//为了再不生成对象直接调用
return s;
}
}
2、懒汉式
eg:
class Single
{
private Single(){}
private static Single s;
private static Single getInstance(){//在函数上直接加锁将每次都会访问锁而降低程序执行效率,下面对此作了优化
if(s==null)
s=new Single();
return s;
}
}
对于上面的是程序如果有多个人同时调用的时候会出现安全问题,因此要进行加锁,结果为
class Single{
private Single(){}
private static Single s;
private static Single getInstance(){
if(s==null)
synchronized(Single.class){//此处加锁是为了保证线程安全
if(s==null)
s=new Single();
}
return s;
}
还有一种处理懒汉式安全问题的方法就是直接在函数方法上加上锁例如:
public static synchronized Single getInstance()
但是这种方法不如前面的方法效率高,以为不管对象是否已经存在每次都要判断一次锁,而上面的只是在一开始的时候有可能判断,
对于懒汉式一般不用因为它的效率要比饿汉式的效率低并且代码繁琐,所以定义单例模式的时候最好使用饿汉式。
继承:
1、提高了代码的复用性
2、继承让类与类之间有了联系,正因为有了这个关系,才有了多态的特性。
注意:千万不要为了获取其他功能,简化代码而继承,必须是类与类之间有所属关系,才可以继承。
java语言中只支持单继承,因为多继承存在安全问题。
子类继承的访问权限:
1、子类和父类在同一个包中的继承性
子类可以继承出private修饰的所有父类成员,集成的访问权限保持不变
2、子类和父类不在同一个包中的继承性
注意: 这时父类或父类接口必须是public修饰的否则无法继承子
类可以继承父类中的有public和protected修饰的父类成员,继承的访问权限保持不变,但是不能继承父类的友好成员
包与包之间的类的成员访问情况:
public protected default private
同一个类 true true true true
同一个包不同类 true true true
子类 true true
不同包中的不同类 true
重写:
1、子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2、静态的只能访问静态的。
用处:
当子类继承父类时,子类筵席了父类的功能,但有的功能无法满足子类的需求,因此可以通过重写的功能改重新定义,这样可以提高程序的扩展性。
注意:覆盖需要看权限和函数名,而重载只需要看参数列表。
子类中构造函数的特点:
在子类进行初始化的时候,父类的构造函数也会执行,这是因为子类中的构造函数第一行有一条默认的隐式super()语句,因此会执行父类的构造函数。
final关键字:
1、可以修饰类、函数、变量
2、被final修饰的类不能被继承,被他修饰的方法不可以被重写
3、被他修饰的变量,是一个常量,只能被复制一次既可以修饰成员变量又可以修饰局部变量。对于他修饰的变量引用对象是不可以改变的,但是变量的内容是可以改变的
例如:
final StringBuffer sb=new StringBuffer("abc");//创建一个容器对象
System.out.println(sb);//输出原来数据为abc
sb.append("ccc");//上容器尾部追加ccc
System.out.println(sb);//打印结果为abcccc
编译通过,因此结论是正确的。
还有一种是:
public static void run(final int a){//当函数调用此函数的时候a的值在可以发生改变,例如调用的是用run(1);run(2)编译也会通过
System.out.println(a);
}
4、内部类定义在局部变量上,只能访问被final修饰的局部变量例如
class test3{
int a=1;
public void run(final int d){
final int c=2;//因为现在的内部类只能访问有final修饰的局部变量
class nei{
public void neiRun(){
int b=a;//内部类可以访问类中的全局变量
b=c;
b=d;
}
}
}
}
final、finally、finalize之间的区别?
final看上面的。
finally:实在try中使用的,是表示必须执行的语句,只有当用到System.exit(0)的时候才不会执行。
finalize:方法名。java技术应用finalize()方法来对垃圾收集器将对象从内存中清除之前做必要的处理工作。这个方法是在垃圾收集器确定对象没有被引用时调用的方法。他是object中的方法。因此所有的类都继承他,可以通过重写的方式来对资源经行整理。
抽象类:(abstract)
当多个类出现相同功能,但是功能主体不同这时可以向上抽取,只抽取功能定义,不抽取功能主题。
抽象类的特点:
1、抽象方法一定在抽象类中
2、抽象方法和抽象类都必须被abstract关键字修饰
3、抽象类不能用new创建对象,也就是不能实例化,必须通过子类来对其功能复写之后,对其子类实例化。如果子类只覆盖部分方法,那么子类还是抽象类。
模板方法---设计模式:
在定义功能的时候,功能的一部分是确定的,但是一部分是不确定的,而确定的部分使用不确定的部分,那么这时就将不确定的部分暴露出去,有该类的子类去完成的方法。
接口:
格式:
interface 名字{
}
接口中的成员修饰符是固定的,且都是public的
eg:
成员变量:public static final .....
成员函数:public static ......
接口的出现将多继承以另一种的方式及多实现的形式体现出来了,接口可以实现多继承例如:
interface A extends B,C{}其中B和C必须也是接口
接口的特点:
1、接口是对外暴露的部分。
2、接口是程序的功能扩展。
3、接口可以实现多实现。
4、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
5、接口与接口之间可以有继承关系
注意:基本功能定义在类中,扩展功能定义在接口中
多态:
定义:某一类事物的多种存在形态。
好处:提高了代码的扩展性和复用性。
弊端:提高了扩展性但只能使用父类的引用访问父类中的成员
注意:我们只能转换的是父类的引用,当父类的引用指向子类的时候,我们可以向上和向下转型
例如:
Animal a =new Cat();
cat c=(Cat)a;
是正确的但是下面的是错误的
Animal a=new Animal();
Cat c=(Cat)a;
多态使用注意事项:
1、对于实例方法在编译的时候看语句的左边,在执行的时候看语句的右边。
2、对于类方法和实例变量以及类变量不管运行还是编译都看语句的左边。
例如:下面程序
public class Practice4 {
public static void main(String[] args){
DuoTai1 fu=new DuoTai2();
System.out.println(fu.a);//打印结果为父类中的a值
System.out.println(fu.b);//打印结果为父类中的b
fu.print();//打印结果为父类中的print
fu.sop();//打印结果为子类中的sop
DuoTai2 zi=(DuoTai2)fu;
System.out.println(zi.a);//打印结果为子类中的a值
System.out.println(zi.b);//打印结果为子类中的b
zi.print();//打印是子类中的
zi.sop();//也是子类中的
}
}
class DuoTai1{
static int a=2;
int b=1;
static void print(){
System.out.println("fu---static");
}
void sop(){
System.out.println("fu---sop");
}
}
class DuoTai2 extends DuoTai1{
int b=2;
static int a=3;
static void print(){
System.out.println("zi---static");
}
void sop(){
System.out.println("zi---sop");
}
}
输出结果为
2
1
fu---static
zi---sop
3
2
zi---static
zi---sop
Object类:
Object类是所有对象的直接后者间接父类,给类定义的功能所有类都可以调用
内部类:
访问规则:
1、内部类可以直接访问外部类的成员,包括私有的,但是如果内部类定义在局部变量的地方,那么此类只能访问带有final修饰的局部变量。
2、外部类访问内部类必须建立内部类对象例如:外部类.this.方法/变量
特点:
1、当内部类定义在成员位置上,而且非私有化可以在外部其他类中直接建立内部类对象
2、当内部类被static修饰后只能直接访问外部类的静态成员和方法。
3、局部内部类是不能静态修饰的,他只能访问用final修饰的局部变量和参数
匿名内部类:
1、匿名内部类其实就是内部类的简写形式
2、定义匿名内部类的前提必须继承一个类或者实现接口
例如
public class Practice5 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Run r=new Run();
r.print(new Speak(){//使用匿名内部类,他继承了Speak接口
void sop(){
System.out.println("测试");
}
});
r.print(new Run().new ZiSpeak());//使用内部类调用方法,这个是创建一个内部类对象
}
}
abstract class Speak{
abstract void sop();
}
class Run{
public void print(Speak s){
s.sop();
}
class ZiSpeak extends Speak{//继承Speak的内部类
void sop(){//覆盖接口中的方法
System.out.println("内部测试");
}
}
}
看上面的程序代码可以看出匿名内部类可以简化书写
还有在外部类中创建内部类的格式为new 外部类().new 内部类()
匿名内部类的格式为new 父类或者接口(){}
3、其实匿名内部类就是个匿名子对象
4、写匿名内部类最好不要超过三个,因为他是为了简化代码而存在的。