zoukankan      html  css  js  c++  java
  • 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 + "
    加分后的成绩:" + 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();
        }
    }


  • 相关阅读:
    【2021-05-18】人生十三信条
    【2021-05-17】打了第一针疫苗
    【2021-05-16】该工作时好好工作,该休息时好好休息
    【2021-05-15】人生十三信条
    【2021-05-14】要保持团队作战的模式
    【2021-05-13】罗马不是一天能建成的
    【2021-05-12】己所不欲勿施于人
    【2021-05-11】服务好了别人,也就服务好了自己
    二维区域和检索
    寻找重复数
  • 原文地址:https://www.cnblogs.com/kuangzhisen/p/6961890.html
Copyright © 2011-2022 走看看