知识列表
- 单例设计模式
- 继承
- 抽象类
- 接口
- 多态
- Object类
- 内部类
- 异常
1)单例设计模式
1: 1: class Single{
2: 2: private Single(){};
3: 3: static Single s = new Single();
4: 4: static Single getInstance(){
5: 5: return s;
6: 6: }
7: 7: }
解决某一类问题最行之有效的方法称为设计模式。
单例设计模式:保证一个类在内存中只有一个对象。保证对象唯一性的步骤:
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。代码实现步骤
1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法可以获取到该对象。对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
单例设计模式有两种表示形式:
①饿汉式
②懒汉式
1: 1: //饿汉式
2: 2: class Single{
3: 3: private Single(){};
4: 4: static Single s = new Single();
5: 5: public static Single getInstance(){
6: 6: return s;
7: 7: }
8: 8: }
9: 9: //懒汉式
10: 10: class Single1{
11: 11: private Single1(){}
12: 12: private static Single1 s = null;
13: 13: public static Single1 getInstance(){
14: 14: if(s==null)
15: 15: s = new Single1();
16: 16: return s;
17: 17: }
18: 18: }
19:
饿汉式,先初始化对象
懒汉式,对象是在方法被调用时才初始化,也叫作对象的延时加载。
一般使用的是饿汉式,因为:
- 设计单例的目的就是为了创建保证对象唯一,并使用这个对象,也就是说对象迟早要被创建。
- 饿汉式安全,懒汉式在多线程时会出现安全隐患。
懒汉式多线程时安全隐患的解决方案:
1: 1: class Single1{
2: 2: private Single1(){}
3: 3: private static Single1 s = null;
4: 4: public static synchronized Single1 getInstance(){//加锁synchronized
5: 5: if(s==null){
6: 6: synchronized(Single1.class){
7: 8: if(s==null)
8: 9: s = new Single1();
9: 10: }
10: 11: }
11: 12: return s;
12: 13: }
13: 14: }
采用双重判断的形式解决懒汉式的安全问题。
所以定义单例时一般使用饿汉式,既简单又安全。
2)继承:
java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,子类对象不确定要运行哪一个。但是java保留这种机制,只是用另一种体现形式,称为多实现。
1: 1: //伪代码
2: 2: class A
3: 3: {
4: 4: void show()
5: 5: {
6: 6: System.out.println("a");
7: 7: }
8: 8: }
9: 9: class B
10: 10: {
11: 11: void show()
12: 12: {
13: 13: System.out.println("b");
14: 14: }
15: 15: }
16: 16:
17: 17: class C extends A,B//如果C同时继承A和B
18: 18: {}
19: 19:
20: 20: C c = new C();
21: 21: c.show();//如果支持多继承,那这里就不知道应该输出a还是b。所以多继承会有安全隐患
java支持多层继承,也就是一个继承体系,那么如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。通过了解共性功能,就可以知道该体系的基本功能。
在具体调用时,要创建最子类的对象,因为:
一是因为有可能父类不能创建对象,
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。简单一句话:查阅父类功能,创建子类对象。
继承的好处:
1,提高了代码的复用性。
2,让类与类之间产生了关系。有了这个关系,才有了多态的特性。3、提高程序的扩展性
注意:千万不要为了获取其他类的功能,简化代码而继承。也就是说要符合生活中的自然规律。不能为了继承而继承,必须是类与类之间有所属关系才可以继承。所属关系 is a。
重载:只看同名函数的参数列表
覆盖:字符类方法要一模一样
final:被final修饰的变量是常量,不会变化,变量名字母全大写,多个单词之间用_分开。一般是共享数据。
3)抽象类:
多个类中出现相同功能,但是功能主体不同,可以进行向上抽取,只抽取功能定义,而不抽取功能主体。?
抽象类的特点:
1,抽象方法一定在抽象类中,抽象方法和抽象类都必须被abstract关键字修饰。
2,抽象类不可以用new创建对象。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
1: abstract class Student
2: {
3: abstract final void study();//抽象方法没有方法体,用分号结束
4: void sleep()
5: {
6: System.out.println("hello world!");
7: }
8: }
抽象举例:
员工包含 3 个属性:姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。 员工类:name id pay ;经理类:继承了员工,并有自己特有的bonus。
1: abstract class Stuff//stuff代表所有员工,包括经理和普通员工
2: {
3: private String name;
4: private String id;
5: private double pay;
6:
7: Stuff(String name,String id,double pay)
8: {
9: this.name = name;
10: this.id = id;
11: this.pay = pay;
12: }
13: public abstract void work();//不论是经理和普通员工都必须工作
14: }
15: class Managers extends Stuff
16: {
17: private int bonus;
18: Managers(String name,String id,double pay,int bonus)
19: {
20: super(name,id,pay);
21: this.bonus = bonus;
22: }
23: public void work()//复写work方法
24: {
25: System.out.println("manager work");
26: }
27: }
28: class Workers extends Stuff
29: {
30: Workers(String name,String id,double pay)
31: {
32: super(name,id,pay);
33: }
34: public void work()//复写work方法
35: {
36: System.out.println("pro work");
37: }
38: }
模板方法设计模式:
定义功能时,有一部分功能是确定的,还有一部分是不确定的,而确定的部分使用了不确定的部分。就将不确定的功能暴露出去,由该类的子类去实现。
举例:
1: abstract class GetTime//获取程序运行时间的类
2: {
3: public final void getTime()
4: {
5: long start = System.currentTimeMillis();
6:
7: runcode();//不确定的运行代码
8:
9: long end = System.currentTimeMillis();
10:
11: System.out.println("毫秒:"+(end-start));
12: }
13: public abstract void runcode();//单独抽取暴露出去
14:
15: }
16: class SubTime extends GetTime
17: {
18: public void runcode()//子类完成不确定的方法。需要被检测时间的代码
19: {
20: for(int x=0; x<4000; x++)
21: {
22: System.out.print(x);
23: }
24: }
25: }
26: class TemplateDemo
27: {
28: public static void main(String[] args)
29: {
30: SubTime gt = new SubTime();
31: gt.getTime();
32: }
33: }
模板方法设计模式,提高了代码了复用性。使用模板方法设计模式时,需要被子类实现的代码不一定是抽象的,可以有方法体,子类覆盖即可。
4)接口
接口定义的特点:
接口中的成员都是public修饰的,如果不写public,系统默认会添加。方法前的public abstract static也可以不写,系统默认添加,但阅读性差
类名:Interface interface
变量:public static final int NUM=2;
方法:public abstract static void show();
接口不能创建对象。
接口可以被类多实现。并且可以在继承一个类的同时继承多个接口。
5)多态:
事物存在的多种体现形态。
多带的体现:父类的引用指向了子类对象
多态的好处:提高了程序的拓展性
多态的前提:类与类之间必须有关系,要么是继承要么是实现。存在覆盖。
多态的局限:只能使用父类的引用访问父类中的成员。
多态中成员函数的特点:
编译时期检查引用型变量所属的类中是否有调用的方法,如果有,编译通过,如果没有就编译失败。
运行时期检查对象所属类中是否有调用的方法。
多态中成员变量的特点:
无论编译和运行都参考引用型变量所属的类
多态中静态成员函数的特点:
和成员变量一样,无论编译和运行都参考引用型变量所属的类
6)Object类
超类,所有类的父类
定义的是所有对象都具备的功能。
7)内部类
1: /*
2: 内部类的访问规则:
3: 1,内部类可以直接访问外部类中的成员,包括私有。
4: 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
5: 2,外部类要访问内部类,必须建立内部类对象。
6: */
7: class Outer
8: {
9: private int x = 3;
10: class Inner//内部类
11: {
12: //int x = 4;
13: void function()
14: {
15: //int x = 6;
16: System.out.println("innner :"+Outer.this.x);//内部类可以直接访问外部类成员
17: }
18: }
19: void method()
20: {
21: Inner in = new Inner();
22: in.function();
23: }
24: }
25: class InnerClassDemo
26: {
27: public static void main(String[] args)
28: {
29: Outer out = new Outer();
30: out.method();
31: }
32: }
33:
如果内部类被静态修饰,就只能访问外部内中的静态成员
如果内部类定义了静态成员,该类就必须是静态的,
外部类中的静态方法要访问内部类时,内部类也必须是静态的。
内部类定义原则:
当描述事物时,事物的内部还有事物时,内部事物就用内部类描述,因为内部事物使用类外部事物的内容。
匿名内部类格式:
new 父类或者接口(){定义子类的内容}
8)异常:
不正常现象的描述。Throwable是所有错误或异常的超类。
分两种:编译时异常(函数上必须申明),运行时异常(函数不必申明)
异常处理
1: try{
2: 被检测代码
3: }
4: catch(异常类 变量){
5: 异常处理代码
6: }
7: finally{
8: 一定会执行的代码
9: }
多异常的处理:
申明异常时应该申明得更为具体,这样处理时才能采取更为具体的方式。
多异常处理时,处理父类异常的catch块应该放在处理子类异常catch块的下面。
异常的处理方式:可以使用日志文件记录下来,便于对代码进行修正
自定义异常
1: class SelfException extends Exception{
2:
3: }
自定义异常继承Exception,原因:
只有Exception体系中de成员才能被throws 和throw操作。可抛性。
throws和throw的区别:
throws使用在函数上。
throw使用在函数内。throws后面跟的异常类。可以跟多个。用逗号隔开。
throw后跟的是异常对象。
自定义异常时,如果异常的发生导致无法继续进行运算,就继承RuntimeException,让程序停止运行。运行时异常,函数内抛出,函数上不必申明。
处理异常格式
1: 第一种格式
2: try{
4: }
5: catch(){
7: }
8: finally{
10: }
12: 第二种格式
13: try{
15: }
16: finally{
18: }
20: 第三种格式
21: try{
23: }
24: catch(){
26: }
没有catch块时必须将异常申明出去。
子类不能抛出比父类更多的异常,父类抛出异常时,子类只能抛出比父类异常的子异常。父类没有抛出异常时,子类如果发生异常必须进行try处理。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------