Java基础回顾 —抽象类、接口、多态
-
抽象类不能实例化。抽象方法必须定义在抽象类中。
如果一类包含了抽象方法,那么这个类一定是抽象类。
如果一个类是抽象类,但是它 可以包含具体方法(有声明有实现)。
tips1 :抽象类不能定义成final的,因为定义成final,就不能被继承,而抽象类必须被继承。
tips2: 抽象类可以定义构造方法,但是不能被实例化。 -
子类继承抽象类,那么子类必须实现父类所有抽象方法,否则该子类也需声明成一个抽象类。
-
接口:地位等同于class,接口中的所有方法都是抽象方法。
一个类实现了接口,那么该类需要实现接口中所有抽象方法(除非该类是抽象类)。
tips1: 接口中的方法就是不写public,默认也是public的,而且全局常量默认public static final的。 -
多态总结: 父类引用指向子类对象,或者接口类型的引用指向实现该接口类的实例(其类型转换方式与父类子类的转换方式完全一样)。
tips1: 对象的多态性可以认为两种形式:向上转型和向下转型。
向上转型:父类 父类对象 = 子类实例;
向下转型:子类 子类对象 = (子类) 父类实例;
如果对象发生了向上转型后,调用的方法一定是被子类覆写过的方法。但是如果是子类的新方法,则父类引用不能调用,此时可以将对象进行向下转型。 -
static关键字
static修饰属性:无论该类生成多少实例,始终共享唯一一份成员变量。一个实例对其修改,则会影响所有实例。
static修饰方法:可以使用类的名字直接访问该方法。 static不能调用任何非static内容的,因为对象中的属性和方法必须在对象开辟内存之后才能调用,而static类型的方法在对象未被实例化时就能被类名调用。 -
静态方法只能继承,而不能重写(只会隐藏父类的方法,最后取决于引用类型,引用类型是父类,则调用父类的方法)。
如果子类的方法没有static,则按道理回去覆盖父类同样的方法,但是父类的方法是static,所以编译报错。
如果子类的方法static,但是父类的方法不是,同样编译不过。
静态的方法不能被覆盖,静态的方法也不能覆盖非静态的。。。。 -
final关键字
final修饰类不能被继承。
final修饰方法不能被重写,不能被覆盖。
final指向值类型时,值不能发生变化;final指向引用类型时,该引用不可以再指向别的对象了,但是当前对象的内容是可以改变的。 -
final 两种赋值:
--声明的时候就赋值;
--在所有的构造方法中赋值。
tips: 一般来说在方法中使用内联方式(直接书写代码)会比方法调用效率更高,如果调用的方法声明为final的,同样也能提高效率,当一个方法声明为final之后,当你编译应用程序时就可以确定该方法的代码,并且编译器可以讲该方法展开插入到调用者代码处,提高了运行速度以及系统效率。所以说声明为final的方法或者类,都能起到内联作用。 -
static静态代码块(类初始化块): 在类加载到虚拟机的时候执行。所有new两个实例,只会在第一次运行static静态代码块。
作用就是完成一些初始化工作。首先执行静态代码,然后执行构造方法。
静态代码块是在类被加载的时候执行,而构造方法是在生成对象的时候执行;要像调用某个类来生成对象,首先需要将类加载到JVM,然后JVM加载这个类来生成对象。
tips: 静态代码块在项目中一般可以用于util包中,定义一个Config类,从配置文件加载信息。
即定义一个 static String properties变量,然后在static代码块中加载properties信息。调用的时候直接使用Config.properties,都不需要实例化Config类(同时需要定义一个 static boolean isLoaded变量来保证初始化操作已完成)。 -
如果继承体系既有构造方法,又有静态代码块,那么首先执行最顶层类的静态代码块,一直到最底层的静态代码块,然后再去执行最顶层类的构造方法,一直到最底层类的构造方法 (构造块在静态代码块和构造方法之间运行)。( static代码块只运行一次)
-
不能在静态方法里面访问一个非静态的成员变量。
非静态的可以访问一切。
不能在静态方法中使用this关键字。 -
Java常用的内存区域:
1)栈内存空间:保存所有对象名称(保存了引用的堆内存空间的地址)
2)堆内存空间:保存每个对象的具体属性内容
3)全局数据区:保存static类型的属性
4)全局代码区:保存了所有的方法定义