Java进阶 --内部类

引用数据类型作为方法的形参和返回值

  • 普通类:
    作为形参:传递的是类或者子类对象,也即是将new 出来的对象传递给方法。
    作为返回值:返回的也是类或者子类的对象。
  • 抽象类:
    作为形参:传递的是子类的对象。
    作为返回值:返回的也是子类的对象。
  • 接口:
    作为形参:传递的是实现类的对象。
    作为返回值:返回的也是实现类的对象。
/*
	定义了一个内部类Outer和一个外部类Inner
*/
public class Outer {

    // 私有成员内部类
    private class Inner implements Inter {
        @Override
        public void innerShow() {
            System.out.println("Inner内部类的innerShow方法被实现");
        }
    }

    // 外部类成员方法,返回一个内部类对象,采用接口多肽的形式返回
    public Inter getInner() {
        return new Inner();
    }

    // 公有成员内部类
    public class Inner2 {
        public void inner2Show() {
            System.out.println("Inner2内部类的inner2Show方法被访问");
        }
    }

    // 公有静态成员内部类
    public static class Inner3 {
        public static void inner3Show() {
            System.out.println("Inner3内部类的inner3Show方法被访问");
        }
    }
}
/*
	接口,主要用途是采用接口多肽的方式来返回内部类对象的
*/
public interface Inter {
    void innerShow();
}
/*
	测试类
*/
public class OuterDemo {
    public static void main(String[] args) {
        // 创建一个Outer对象
        Outer o = new Outer();

        Inter i = o.getInner();
        i.innerShow();

        // 创建对象
        Outer.Inner2 i2 = new Outer().new Inner2();
        i2.inner2Show();

        // 直接用类名就可以访问公有静态内部类的方法
        Outer.Inner3.inner3Show();
    }
}
  • 总结:
    1. 如果形参或者返回值是普通类类型,传递或者返回的就是该类或其子类对象。
    2. 如果形参或者返回值是抽象类类型,传递或者返回的就是它子类对象。
    3. 如果形参或者返回值是接口类型,传递或者返回的就是它实现类对象。

内部类

  • 概念:在一个类内部定义的类就叫做内部类。内部类可以分为:成员内部类、局部内部类、匿名内部类。

  • 内部类的目的:一般只需要在当前类中使用某个类的对象,那么这个类就可以定义成内部类,而且被private修饰,外面无法直接访问。

  • 成员内部类:在类中方法外定义的内部类就是成员内部类。

    注意:

  1. 如果成员内部类是public修饰的,那么外界可以直接访问。
    外部类.内部类 对象名=new 外部类().new 内部类();
  2. 如果成员内部类是public static 修饰的,外界也可以直接访问。
    外部类.内部类 对象名=new 外部类.内部类();
  3. 如果成员内部类是private修饰的,那么外界无法直接方法,只能在内部类所在的外部类创建该内部类对象。
  • 局部内部类:在方法内部创建的类就是局部内部类。

  • 匿名内部类:一般在开发中使用匿名内部类的形式创建抽象类的子类对象或者接口的实现类对象。仅仅只是简化书写子类或者实现类的过程。

常见用法:作为方法的参数值传递

			//创建饲养员类,让动物吃东西
            AnimalOperator operator=new AnimalOperator();
            //调用useAnimal方法操作动物吃东西
            operator.useAnimal(new Animal() {
                @Override
                public void eat() {
                    System.out.println("?吃骨头");
                }
            });

案例:

```java
/*
    抽象类
 */
public abstract class Animal {
    public abstract void eat();
}
/*
    接口
 */
public interface Jumpping {
    void jump();
}
/*
	饲养员操作类
*/
public class AnimalOperator {
    public void userAnimal(Animal a) {
        a.eat();
    }
}
public class Demo {
    public static void main(String[] args) {
        // 使用匿名内部类的方式创建抽象类Animal对象
        Animal a=new Animal(){
            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }
        };

        // a为匿名内部类的对象名,并且调用匿名内部类中的方法
        a.eat();

        // // 使用匿名内部类的方式创建接口Jumpping对象
        Jumpping j=new Jumpping(){
            @Override
            public void jump() {
                System.out.println("猴子跳高");
            }
        };

        // // j为匿名内部类的对象名,并且调用匿名内部类中的方法
        j.jump();

        AnimalOperator ao = new AnimalOperator();
        ao.userAnimal(new Animal() {
            @Override
            public void eat() {
                System.out.println("我是老虎,喜欢吃肉");
            }
        });

        ao.userAnimal(new Animal() {
            @Override
            public void eat() {
                System.out.println("我是莱恩,放大专吃人");
            }
        });
    }
}

### 常用api:(知道每个类是干什么用的,会查api文档即可)
- Math:跟数学运算相关的对象
            `public static double ceil​(double a):向上取整`
           ` public static double floor​(double a):向下取整
`
- System:
            `static long	currentTimeMillis​() :获取系统当前时间的毫秒值。`
            毫秒值:比秒还小一级的时间单位,1秒=1000毫秒。这里获取的毫秒值是距离1970年1月1日0点0分0秒0的值

- Object:所有的类的父类(超类、基类)。所有类都直接或者间接继承了Object类:
            `String	toString​():返回对象的字符串表示形式`
所有对象都可以调用toString方法,如果该类重写了toString方法(Alt+Insert/ins生成),那么返回的结果就是成员变量的内容。如果没有重写toString方法,那么返回的是该对象的地址值。

 ps:System.out.println(对象名);实际上会调用对象的toString方法。

` boolean	equals​(Object obj):指示一些其他对象是否等于此。`
        
所有对象都可以调用equals方法,如果该类没有重写equals方法,那么比较的是对象的地址值。如果需要比较对象的内容,那么就需要重写
该方法(Alt+Insert/ins生成)。
ps:String类就重写了equals方法,所以比较字符串的时候使用的是equals方法而不是==比较。

例如:
   
```java
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        //if (o == null || getClass() != o.getClass()) return false;

        if (o == null || !(o instanceof Student)) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

}
public class ObjectDemo {
    public static void main(String[] args) {
        Student stu1 = new Student("ldl", 26);

        Student stu2 = new Student("ldl", 26);

        boolean result = stu1.equals(stu2);
        System.out.println("result = " + result); // true


    }
}
  • Arrays:该类包含用于操作数组的各种方法(如排序和搜索)
    static void sort​(int[] a):排序方法,从小到大排序

static String toString​(任意类型数组):将数组中的内容以字符串的形式输出,如果数组是对象类型的数组,那么会调用每个对象的toString方法

  • 类似于Math、Arrays类,它们不需要创建对象,方法都是静态方法,这种类我们可以把它称作工具类。
    1、构造方法都被private修饰
    2、方法都是public static修饰的。
    3、有的工具类还会被final修饰,不能被继承。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章