final关键字
1.修饰符变量--->常量,运行的过程中无法重新赋值。
2.修饰符方法--->最终的方法,在子类中无法重写
3.修饰类--->最终的类,不能被继承。
抽象类
抽象方法
使用abstract修饰的方法。
抽象方法的特征:没有方法体。
抽象类
使用abstract修饰的类,抽象类中可以包含抽象方法。
包含抽象方法的类一定是抽象类,但抽象类中不一定包含抽象方法。
抽象类中可以存在属性,方法,构造方法。
抽象类不能实例化(不能使用new关键字创建对象),但可以在子类调用构造方法。
抽象类的作用:通过抽象类,可以避免子类设计的随意性。
抽象类就是为被继承而生的。
子类一旦继承了抽象类,就必须重写抽象类中的抽象方法,或者子类本身也是一个抽象类。
设计模式
设计模式:经典问题的解决方案,java中总共有23中设计模式,每一种设计模式都在解决一类特点的问题。
单例模式
单例模式:保证一个类只能有一个实例。
特征:构造方法私有化,提供一个静态的方法获取实例
常见的实现方法:
1.恶汉式
2.懒汉式
简单工厂模式
简单工厂模式又叫静态工厂方法,可以通过其生成产品,可以降低因生成生成产品而导致的耦合性过强。(解耦合)
*如何实现工厂模式?
* 1.编写父类和子类或接口和实现类
* 2.编写静态的工厂方法,返回值类型为父类或接口。--->多态
* 3.根据用户的需求动态创建子类的实例,并返回。
public class AxeFactory {
/**
* 负责创建产品(斧头)
* @param ch
* @return
*/
public static Axe getInstance(String ch){
Axe axe=null;
if(ch.equals("steel")){
axe = new SteelAxe();
}else if(ch.equals("stone")){
axe = new StoneAxe();
}
return axe;
}
public static void main(String[] args) {
Axe axe = AxeFactory.getInstance("steel");
axe.chop();
System.out.println("*********************");
Axe axe2 = AxeFactory.getInstance("stone");
axe2.chop();
}
接口
接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。
接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想
接口定义和特点
接口定义:使用interface关键字
* [修饰符] interface 接口名 [extends 父接口1,父接口2...]{
* //常量的声明
* //方法的声明
* }
*接口成员的特点:
*1.接口中所有的成员变量是常量,默认修饰符为public static final
*2.接口中所有的方法都是抽象方法,默认修饰符为:public abstract
*3.接口不能实例化,接口不能构造方法(抽象类不能实例化,但可以有构造方法)
*4.java类是单继承,但接口可以是多继承
*5.一个非抽象类实现实现接口,必须重写接口中的抽象方法,抽象类实现接口可以重写部分抽象方法。
*6.一个类只能继承一个父类,但可以实现多个接口
*
*如果一个类继承父类并实现了接口如何编写?
* [修饰符] class 类名 [extends 父类名 implements 接口名1,接口名2..]{
* }
* eg:
* public class E extends D implements A,B{
*
* }
Comparable接口
* java.lang.Comparable接口:此接口强行对实现它的每个类的对象进行整体排序。
* 排序规则在compareTo()方法中定义。
* 当调用java.util.Arrays类中sort(Object[] objs)时,
* 程序会调用compareTo()方法对对象进行比较,
* 如果该方法返回正整数(1)时,代表当前对象大于待比较对象;
* 如果返回0,代表当前对象等于待比较对象
* 如果该方法返回负整数(-1)时,代表当前对象小于待比较对象;
*实现思路:
*1.实现Comparable接口,并重新其compareTo方法
*2.在compareTo方法中定义比较规则。返回值应该是正整数,零和负整数。
*3.在调用Arrays.sort(Object[] objs)方法的过程中,sort方法的内部对调用compareTo方法进行比较。
Comparator接口
* java.util.Comparator接口:比较器
* int compare(Object o1, Object o2):比较用来排序的两个参数。
* 根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
内部类
*内部类:将一个类定义置入另一个类定义中就叫作“内部类”
*特点:
*1.内部类可以访问外部的成员,但外部类不能访问内部的成员。
*2.外部类的修饰符只有两种:public和默认,而内部类的修饰符可以是public,protected,默认,private
*3.内部类成员只有在内部类的范围之内是有效的。
*4.用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
*内部类的分类:成员内部类,静态内部类,方法内部类,匿名类。
成员内部类
public class OuterClass {
//外部类的成员
private String name="zhangsan";
private int num=10;
//外部类的方法
public void outerMethod(){
// System.out.println(a);//外部类不能访问内部类的成员
}
//内部类
public class InnerClass{
//内部类的成员
private int num=20;
private int a=30;
//内部类的方法
public void innerMethod(){
System.out.println("OuterClass--->name="+name);//内部类可以访问外部类的成员
System.out.println("OuterClass--->num="+OuterClass.this.num);//外部类的成员
System.out.println("InnerClass--->num="+this.num);//内部类的成员
}
}
public static void main(String[] args) {
/*
* 创建内部类的实例:
* 外部类.内部类 对象名 = new 外部类().new 内部类();
*/
OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();
innerClass.innerMethod();
}
静态内部类
静态内部类:使用static修饰的内部类。静态内部只能访问外部的静态成员。
public class OuterClass2 {
//外部类的成员
private static String name="zhangsan";
private static int num=10;
//外部类的方法
public void outerMethod(){
// System.out.println(a);//外部类不能访问内部类的成员
}
//内部类
public static class InnerClass{
//内部类的成员
private int num=20;
private int a=30;
//内部类的方法
public void innerMethod(){
System.out.println("OuterClass--->name="+name);//内部类可以访问外部类的成员
System.out.println("OuterClass--->num="+OuterClass2.num);//外部类的成员
System.out.println("InnerClass--->num="+this.num);//内部类的成员
}
}
public static void main(String[] args) {
/*
* 创建静态内部类的实例:
* 外部类.内部类 对象名 = new 外部类.内部类();
*/
OuterClass2.InnerClass innerClass = new OuterClass2.InnerClass();
innerClass.innerMethod();
}
}
方法内部类
方法内部类:在方法中定义的内部类。如果方法内部类中需要访问方法中局部变量,该局部变量必须使用final修饰
public class OuterClass3 {
// 外部类的成员
private String name = "zhangsan";
private int num = 10;
// 外部类的方法
public void outerMethod(){
//方法内部类
class InnerClass{
//内部类的成员
private final int num=20;
private int a=30;
//内部类的方法
public void innerMethod(){
System.out.println("OuterClass--->name="+name);//内部类可以访问外部类的成员
System.out.println("OuterClass--->num="+OuterClass3.this.num);//外部类的成员
System.out.println("InnerClass--->num="+num);//内部类的成员
}
}
InnerClass innerClass = new InnerClass();
innerClass.innerMethod();
}
public static void main(String[] args) {
OuterClass3 outerClass = new OuterClass3();
outerClass.outerMethod();
}
}
匿名内部类
匿名内部类Anonymous
可以实现一个接口,或者继承一个父类
只能实现一个接口
适合创建那种只需要一次使用的类,不能重复使用。比较常见的是在图形界面编程GUI里用得到。
匿名内部类要使用外部类的局部变量,必须使用final修饰该局部变量
public class TestAnonymous {
public static void main(String[] args) {
//实现一个接口的匿名内部类
/*
* class MyClass implements MyInterface{
* public void test(){
* ..
* }
* }
* MyClass myClass = new MyClass();
* myClass.test();
*/
new MyInterface() {
public void test() {
System.out.println("测试匿名内部的test方法....");
}
}.test();
/*
* 继承的匿名类。
* class MyThread extends Thread{
* public void run(){
* ....
* }
* }
* MyThread myThread = new MyThread();
* myThread.start();
*/
new Thread(){
public void run() {
System.out.println("Thread....run方法...");
}
}.start();
}
}
java垃圾回收机制
对象空间的分配:
使用new关键字创建对象即可
对象空间的释放:
传统的C/C++语言,需要程序员负责回收已经分配内存。显式回收垃圾回收的缺点:
程序忘记及时回收,从而导致内存泄露,降低系统性能。
程序错误回收程序核心类库的内存,导致系统崩溃。
Java语言不需要程序员直接控制内存回收,是由JRE在后台自动回收不再使用的内存,称为垃圾回收机制(Garbage Collection)。
可以提高编程效率。
保护程序的完整性。
其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的。
垃圾回收机制只回收JVM堆内存里的对象空间。
对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力
垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。
可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。
垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。
永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。