接口:
*接口定义:使用interface关键字
* [修饰符] interface 接口名 [extends 父接口1,父接口2...]{
* //常量的声明
* //方法的声明
* }
*接口成员的特点:
*1.接口中所有的成员变量是常量,默认修饰符为public static final
*2.接口中所有的方法都是抽象方法,默认修饰符为:public abstract
*3.接口不能实例化,接口不能构造方法(抽象类不能实例化,但可以有构造方法)
*4.java类是单继承,但接口可以是多继承
*5.一个非抽象类实现实现接口,必须重写接口中的抽象方法,抽象类实现接口可以重写部分抽象方法。
*6.一个类只能继承一个父类,但可以实现多个接口
*7.接口中被重写N次的方法,最后调用,调用的都是最后一次被重写的方法。
*如果一个类继承父类并实现了接口如何编写?
* [修饰符] class 类名 [extends 父类名 implements 接口名1,接口名2..]{
* }
* eg:
* public class E extends D implements A,B{
*
* }
public interface A { void m1();//public abstract void m(); }
public interface B { void m2(); }
public interface C extends A,B{ // void m1();//从接口A继承而来 // void m2(); //从接口B继承而来 void m3(); }
public class D { public void test(){ System.out.println("D类中的test方法....."); } }
/** *因为抽象类中是可以存在抽象方法的,所以一个抽象类实现了接口,可以重写或不重新接口中的抽象方法。 * */ public abstract class F implements C{ // public abstract void m1(); // public abstract void m2(); // public abstract void m3(); }
/** * 该类继承了父类D并实现了接口A和接口B * 必须实现(重写)接口A和接口B的抽象方法 * */ public class E extends D implements A,B{ @Override public void m2() { System.out.println("实现了接口B中的m2抽象方法"); } @Override public void m1() { System.out.println("实现了接口A中m1抽象方法"); } public static void main(String[] args) { E e = new E();//类本身进行new e.m1(); e.m2(); e.test(); System.out.println("-------------------------"); D e2 = new E();//用父类new子类,向上转型,只能访问父类中的test方法 e2.test(); System.out.println("-------------------------"); A e3 = new E();//利用接口A创建实现类,向上转型,只能访问接口A中定义的m1方法 e3.m1(); System.out.println("--------------------------"); B e4 = new E();//利用接口B创建实现类,只能访问接口A中定义的m2方法 e4.m2(); } }
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方法进行比较。
public class Student { private String name; private int age; private int score; public Student(String name, int age, int score) { super(); this.name = name; this.age = age; this.score = score; } public Student() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", score=" + score + "]"; } }
public class TestArray { /* * 按照年龄进行排序,冒泡 * N个数字来排队,两两比较小靠前, * 外层循环N-1(需要比较的轮数) * 内存循环N-1-i(每轮需要比较的次数) */ public static void sort(Student[] stus){ for(int i=0;i<stus.length-1;i++){ for(int j=0;j<stus.length-1-i;j++){ //先从学生对象中获取该学生的年龄 if(stus[j].getAge()>stus[j+1].getAge()){ //交换位置 Student temp=stus[j]; stus[j]=stus[j+1]; stus[j+1]=temp; } } } } public static void main(String[] args) { Student[] stus = new Student[5];//保存学生信息的数组 stus[0]=new Student("aa",20,80); stus[1]=new Student("bb",22,78); stus[2]=new Student("cc",18,90); stus[3]=new Student("dd",25,82); stus[4]=new Student("ee",24,81); System.out.println("排序前:"); for (Student student : stus) { System.out.println(student); } sort(stus);//排序 System.out.println("排序后:"); for (Student student : stus) { System.out.println(student); } } }
Comparable接口:
public class Student implements Comparable{ private String name; private int age; private int score; public Student(String name, int age, int score) { super(); this.name = name; this.age = age; this.score = score; } public Student() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", score=" + score + "]"; } /** * 制定比较规则: * compareTo(Object o):比较当前对象与指定对象o之间的关系。 * 如果当前对象大于指定对象o返回值是正整数 * 如果当前对象等于指定对象o返回值是零 * 如果当前对象小于指定对象o返回值是负整数 */ @Override public int compareTo(Object o) { Student stu = (Student)o; // if(age>stu.getAge()){ // return 1; // }else if(age==stu.getAge()){ // return 0; // }else{ // return -1; // } return (age-stu.getAge()); } }
import java.util.Arrays; /** *java.util.Arrays类 *sort(Object[] objs):根据元素的自然顺序对指定对象数组按升序进行排序。数组中的所有元素都必须实现 Comparable接口 * */ public class TestArrays { public static void main(String[] args) { Student[] stus = new Student[5];//保存学生信息的数组 stus[0]=new Student("aa",20,80); stus[1]=new Student("bb",22,78); stus[2]=new Student("cc",18,90); stus[3]=new Student("dd",25,82); stus[4]=new Student("ee",24,81); System.out.println("排序前:"); for (Student student : stus) { System.out.println(student); } Arrays.sort(stus); System.out.println("排序后:"); for (Student student : stus) { System.out.println(student); } } }
Comparator接口:比较器:
import java.util.Comparator; /** * java.util.Comparator接口:比较器 * int compare(Object o1, Object o2):比较用来排序的两个参数。 * 根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。 * */ public class ScoreComparator implements Comparator{ /** * 定义比较规则:按照分数的降序进行排列 */ @Override public int compare(Object o1, Object o2) { Student stu1=null; Student stu2=null; if(o1 instanceof Student){ stu1=(Student)o1; } if(o2 instanceof Student){ stu2=(Student)o2; } // if(stu1.getScore()>stu2.getScore()){ // return 1; // }else if(stu1.getScore()==stu2.getScore()){ // return 0; // }else{ // return -1; // } return -(stu1.getScore()-stu2.getScore()); } }
import java.util.Arrays; import cn.zzsxt.oop4.Student; /** * java.util.Arrays类 * sort(Object[] objs,Comparator c):按照指定的比较器对指定数组进行排序。 * */ public class TestArrays { public static void main(String[] args) { Student[] stus = new Student[5];//保存学生信息的数组 stus[0]=new Student("aa",20,80); stus[1]=new Student("bb",22,78); stus[2]=new Student("cc",18,90); stus[3]=new Student("dd",25,82); stus[4]=new Student("ee",24,81); System.out.println("排序前:"); for (Student student : stus) { System.out.println(student); } Arrays.sort(stus, new ScoreComparator());//利用指定的比较器完成比较 System.out.println("排序后:"); for (Student student : stus) { System.out.println(student); } } }
*内部类:将一个类定义置入另一个类定义中就叫作“内部类”
*特点:
*1.内部类可以访问外部的成员,但外部类不能访问内部的成员。
*2.外部类的修饰符只有两种:public和默认,而内部类的修饰符可以是public,protected,默认,private
*3.内部类成员只有在内部类的范围之内是有效的。
*4.用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
*成员内部类:将一个类作为另外一个类的成员
*内部类的分类:成员内部类,静态内部类,方法内部类,匿名类。
*成员内部类:将一个类作为另外一个类的成员
*静态内部类:使用static修饰的内部类。静态内部只能访问外部的静态成员。
public class Outclass {//外部类 private String name="name"; private int num1=1; public void show1(){ System.out.println("外部方法"); } public class intclass{//内部类 private int num1=2; public void show(){ System.out.println("内部方法"); System.out.println(num1); System.out.println(name);//访问外部类的不同名成员 System.out.println(Outclass.this.num1);//访问外部类的同名成员 show1();//访问外部类的方法 } } public static void main(String[] args) { Outclass o=new Outclass(); /* * 创建内部类的实例: * 外部类.内部类 对象名 = new 外部类().new 内部类(); */ Outclass.intclass i=new Outclass().new intclass(); // i.show1(); 不能调用外部类的成员和方法 i.show(); } }
静态内部类:
/* *静态内部类:使用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(); } }
方法内部类:
1.在方法中定义的内部类。
2.如果该内部类需要访问方法中局部变量,该局部变量前必须加final。
3.方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
//外部类 public class HelloWorld { private String name = "考试课程"; // 外部类中的show方法 public void show() { // 定义方法内部类 class MInner { int score = 78; public int getScore() { return score + 10; } } // 创建方法内部类的对象 MInner mi = new MInner(); // 调用内部类的方法 int newScore = mi.getScore(); System.out.println("姓名:" + name + " 加分后的成绩:" + newScore); } // 测试方法内部类 public static void main(String[] args) { // 创建外部类的对象 HelloWorld mo = new HelloWorld(); // 调用外部类的方法 mo.show(); } }
匿名内部类:
/** * 匿名内部类:没有名称的内部类 * 匿名内部类可以实现一个接口或继承一个父类. */ 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(); } }
* GC:
垃圾回收机制,有虚拟机自动调用,程序员无法精确控制。
其开销影响性能,java虚拟机必须跟踪程序中有用的对象,确定哪些无用的。
只回收JVM堆内存里的对象空间
* GC机制的优点:
* 1.提高编程效率,摈弃了C/C++中的指针,避免因遗忘释放内存而导致的内存泄漏。
* 2.保证了程序的完整性。
* GC原理:
JVM中有一个线程专门用于回收堆内存中不使用对象,常用的方法:
* 1.定时扫描堆中不使用的对象
* 2.通过计数控制回收时机。
* 什么数据会被垃圾回收?
* 垃圾回收机制回收的堆内存中的对象信息,不能回收物理连接,数据库连接,输入/输出和Socket。
* 当对象不再使用时推荐将该对象的引用更改null,暗示 垃圾回收器优先处理。
* 建议虚拟机进行垃圾回收的方法:
可以设置为null,暗示GC回收
System.gc()或Runtime.getRunTime().gc();
finalize()在垃圾回收前调用,可以在该方法中编写一些垃圾回收前想做事情的代码。
不建议程序员手工调用,该方法是由JVM自动调用GC
public class Student { String name; public Student(String name){ this.name=name; } /** * finalize()在垃圾回收前调用,可以在该方法中编写一些垃圾回收前要做的事情的代码 * 不建议程序员手工调用,该方法是有JVM在垃圾回收前自动调用 */ @Override protected void finalize() throws Throwable { System.out.println("finalize()被调用了"); } }
public class TestGc { public static void main(String[] args) { Student stu = new Student("张三"); System.out.println(stu); stu=null; //建议垃圾回收器回收垃圾 System.gc(); } }