java:面向对象(接口(续),Compareble重写,Comparator接口:比较器的重写,内部类,垃圾回收机制)

接口:

*接口定义:使用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 + "\n加分后的成绩:" + 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();
    }
}

 



posted @ 2017-06-08 11:23  咫尺天涯是路人丶  阅读(1063)  评论(0编辑  收藏  举报