java-面向对象(五)

一、关键字 static

1.static关键字的使用

static可以用来修饰:属性、方法、代码块、内部类

static修饰属性:静态变量(或类变量)

●我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。类似于舍友有属于自己的床,但共用一个卫生间。
●静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
●静态变量的加载要早于对象的创建。
●由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。

类变量与实例变量的内存解析

2.使用static修饰方法:静态方法

●静态方法中,只能调用静态的方法或属性。而非静态方法中,静态和非静态的方法或属性都可以调用
●在静态方法中,不能使用this关键字、super关键字。
●操作静态属性的方法,通常设置为static的
●工具类的方法,习惯上声明为static
●类中的常量常常声明为static

3.单例设计模式

●设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。设计模免去我们自己再思考和摸索。式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,”套路”
●所谓类的单例设计模式,就是采取- -定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生-一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

案例

    package shejimoshi;
    public class SingletonTest {
	    public static void main(String[] args) {
		    Bank bank1 = Bank.getInstance();
		    Bank bank2 = Bank.getInstance();
		    System.out.println(bank1 == bank2);//true
		
		    Order order1 = Order.getInstance();
		    Order order2 = Order.getInstance();
		    System.out.println(order1 == order2);//true
	    }
    }
//饿汉式,线程安全,但加载时间相对较长
    class Bank{
	    //1.私有化类的构造器
	    private Bank(){
		
	    }
	    //2.内部创建类的对象,并且声明静态
	    private static Bank instance = new Bank();
	    //3.提供公共的静态的方法,返回 类的对象
	    public static Bank getInstance(){
		    return instance;
	    }	
    }
    //懒汉式,延迟对象创建,但目前写法线程不安全
    class Order{
	    //1.私有化类的构造器
	    private Order(){
			
	    }
	    //2.声明当前类的对象,不初始化并且声明静态
	    private static Order instance = null;
	    //3.声明public、static的返回当前类对象的方法
	    public static Order getInstance(){
		    if(instance == null){
		    	    instance = new Order();
	        	}
		    return instance;
	    }
    }

减少了系统性能开销。

单例模式应用场景

➢网站的计数器,一般也是单例模式实现,否则难以同步。
➢应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。➢数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
➢项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
➢Application也是单例的典型应用
➢Windows的TaskManager(任务管理器)就是很典型的单例模式
➢Windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

二、代码块

1.代码块的作用

初始化类、对象

2.静态代码块、

static{
        //初始化类的信息
}

●内部可以有输出语句
●随着类的加载而执行,而且只执行一次
●初始化类的信息
●如果一个类中定义了多个静态代码块,则按照先后顺序来执行
●静态代码块的执行要优先于非静态代码块的执行
●静态代码块内只能带哦也静态的属性、静态的方法

3.非静态代码块

{
        //对对象的属性等进行初始化
}

●内部可以有输出语句
●随着对象的创建而执行
●每创建一个对象,就执行一次非静态代码块
●可以在创建对象时,对对象的属性等进行初始化
●如果一个类中定义了多个静态代码块,则按照先后顺序来执行

三、final 关键字

●final意为最终的,可以用来修饰类、方法、变量
●final修饰的类,不能被其他类所继承
●final修饰的方法,表名此方法不可以被重写
●final修饰的变量,此时的"变量"就称为是一个常量
●final修饰属性,可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化。
●final修饰局部变量,使用final修饰形参时,表名此形参是一个常量。不能再重新赋值。
●static final 用来修饰属性:全局常量

四、抽象类与抽象方法

随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。

1.abstract 关键字的使用

abstract 意为抽象的,可以用来修饰类、方法。

abstract 修饰类:抽象类

abstract class 类名{
    //空参构造器;
    //带参构造器
    //方法
}

●此类不能实例化
●抽象类中一定有构造器,便于子类实例化时调用(涉及子类对象实例化的全过程)
●开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作

abstract修饰方法:抽象方法

public abstract void 方法名();

●抽象方法只有方法的声明,没有方法体
●包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法。
●若子类重写了父类中的所有抽象方法后,此子类方可实例化
●若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要用abstract修饰

abstract 使用方法上的注意点

●abstract 不能用来修饰:属性、构造器等结构。
●abstract 不能用来修饰私有方法、静态方法、final的方法、final的类

多态的应用:模板方法设计模式

抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。

解决的问题:

➢当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
➢换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式

模板方法设计模式是编程中经常用得到的模式。各个框架、类库中都有他的影子,比如常见的有:

●数据库访问的封装
●Junit单元测试
●JavaWeb的Servlet中 关于doGet/doPost方法调用
●Hibernate中 模板程序
●Spring中 JDBC Temlate、Hibernate Template等

五、接口

1.概念

●一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。
●另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有继承的关系,仅仅是具有相同的行为特征而已。例如:鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等都支持USB连接。
●接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要...则必须能...”的思想。继承是一个"是不是"的关系,而接口实现则是"能不能"的关系。
●接口的本质是契约,标准,规范,就像我们的法律一样。制定好后大家都要遵守。

2.接口的使用

●接口用 interface 定义
●Java中,接口和类是并列的两个结构
●接口中不能定义构造器,意味着接口不能实例化
●Java开发中,接口通过让类去实现(implements)的方式来使用,如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化。如果实现类没有覆盖接口中的所有抽象方法,则此实现类仍为一个抽象类。

Java类可以实现多个接口 ---> 弥补了Java单继承性的局限性

格式:class AA extends BB implements CC,DD,EE

●接口与接口之间可以继承,而且可以多继承。

JDK7以前:只能定义全局变量和抽象方法

全局常量:public static final... ,书写时可以省略不写
抽象方法:public abstract...

JDK8:除了定义全局常量和抽象方法之外,还可以定义静态的方法、默认方法

●接口中定义的静态方法,只能通过接口来调用。
●通过实现类的对象,可以调用接口中的默认方法。
●如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。 --> 类优先原则
●如果实现类实现了多个接口,而这个接口中定义了同名同参数的默认方法,那么在实现类中没有重写此方法的情况下,报错。
●在子类(或实现类)的方法中调用父类、接口中被重写的方法。super.xx(),interface_name.super.xx()

3.接口的应用:工厂模式

工厂模式实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

六、内部类的使用

1.概念

●Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
●成员内部类:一方面,作为一个类可以定义属性、方法、构造器等,可以被final修饰,表示此类不能被继承,可以被abstract修饰;另一方面,可调用外部类的结构,可被static修饰,可以被4中不同的权限修饰。
●局部内部类(方法内、代码块内、构造器内)。

原文地址:https://www.cnblogs.com/nnadd/p/12766539.html