day16_常见引用类型作为行参和返回值丶内部类

常用的引用类型用法总结

实际的开发中,引用类型的使用非常重要,也是非常普遍的。我们可以在理解基本类型的使用方式基础上,进一步去掌握引用类型的使用方式。基本类型可以作为成员变量、作为方法的参数、作为方法的返回值,那么当然引用类型也是可以的。

类名作为形参和返回值

  • 类名作为方法的形参: 方法的形参是类名,其实需要的是该类的对象.实际传递的是该对象的【地址值】
  • 类名作为方法的返回值:方法的返回值是类名,其实返回的是该类的对象。 实际传递的,也是该对象的【地址值】

抽象类作为形参和返回值

  • 方法的形参是抽象类名:其实需要的是该抽象类的子类对象
  • 方法的返回值是抽象类名:其实返回的是该抽象类的子类对象

接口名作为形参和返回值

  • 方法的形参是接口名:其实需要的是该接口的实现类对象
  • 方法的返回值是接口名:其实返回的是该接口的实现类对象

数组作为方法参数和返回值

  • 数组作为方法参数传递,传递的参数是数组内存的地址。
  • 数组作为方法的返回值,返回的是数组的内存地址

总结:

方法的参数为基本类型时,传递的是数据值. 方法的参数为引用类型时,传递的是地址值.

内部类

概念:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。成员内部类 :定义在类中方法外的类  局部内部类:定义在类中方法里的类。

成员内部类的定义格式:

内部类的访问特点

  • 内部类可以直接访问外部类的成员,包括私有
  • 外部类要访问内部类的成员,必须创建对象

示例

package demo03;

public class Outer {
    private int num = 10;

    public class Inner {

        public void show() {
            //   内部类可以直接访问外部类的成员,包括私有
            System.out.println(num);
        }

    }

    public void method() {
        // 外部类要访问内部类的成员,必须创建对象
        Inner i = new Inner();
        i.show();
    }

}

成员内部类

  • 定义位置:在类中方法,跟成员变量是一个位置

外界创建成员内部类

格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

举例:

Outer.Inner oi = new Outer().new Inner();

成员内部类作为类的成员的角色(看成一个成员变量):

  • 和外部类不同,Inner class还可以声明为private或protected;
  • 可以调用外部类的结构
  • Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

成员内部类作为类的角色(看成一个类):

  • 可以在内部定义属性、方法、构造器等结构
  • 可以声明为abstract类 ,因此可以被其它的内部类继承
  • 可以声明为final的
  • 编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)

小结

  • 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员内部类中才可声明static成员。
  • 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
  • 成员内部类可以直接使用外部类的所有成员,包括私有的数据
  • 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的

局部内部类

  • 定义位置:局部内部类是在方法中定义的类

格式:

局部内部类使用方式

  • 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
  • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
局部内部类的特点
  • 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号,以及数字编号。
  • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
  • 局部内部类可以使用外部类的成员,包括私有的。
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
  • 局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
  • 局部内部类不能使用static修饰,因此也不能包含静态成员

示例

package demo03;

class Outer {
    private int num = 10;

    public void method() {
        int num2 = 20;
        class Inner {//局部内部类

            public void show() {
                //直接访问外部类的成员,也可以访问方法内的局部变量
                System.out.println(num);
                System.out.println(num2);
            }
        }
        //局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
        Inner i = new Inner();
        i.show();
    }
}

匿名内部类

匿名内部类属于局部内部类其中的一种。匿名内部类 :是内部类的简化写法。它的本质是一个 带具体实现的 父类或者父接口的 匿名的 子类对象。开发中,最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作,

  1. 定义子类
  2. 重写接口中的方法
  3. 创建子类对象
  4. 调用重写后的方法

我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。

前提:
  • 匿名内部类必须继承一个父类或者实现一个父接口。

格式

对格式“new 接口名称() {...}”进行解析:

  • new代表创建对象的动作
  • 接口名称就是匿名内部类需要实现哪个接口
  • {...}这才是匿名内部类的内容
匿名内部类的特点
  • 匿名内部类必须继承父类或实现接口
  • 匿名内部类只能有一个对象
  • 匿名内部类对象只能使用多态形式引用

匿名内部类在开发中的使用

  • 当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码

以接口举例:

定义接口

package demo04;
/*
    飞行接口
 */
public abstract class FlyAble {
    public abstract void fly();
}

创建匿名内部类,并调用:

package demo04;

public class InnerDemoTest {
    public static void main(String[] args) {
        /*
        1.等号右边:是匿名内部类,定义并创建该接口的子类对象
        2.等号左边:是多态赋值,接口类型引用指向子类对象
          */
    }

    FlyAble f = new FlyAble() {
        public void fly() {
            System.out.println("我飞了~~~");
        }
    };//调用 fly方法,执行重写后的方法 f.fly(); 
}

通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:

package demo04;

public class Demo {
    public static void main(String[] args) { /*创建匿名内部类,直接传递给showFly(FlyAble f) */
        showFly(new FlyAble() {
            public void fly() {
                System.out.println("我飞了~~~");
            }
        });
    }

    public static void showFly(FlyAble f) {
        f.fly();
    }
}

另外还要注意几点问题:

  • 匿名内部类,在【创建对象】的时候,只能使用唯一一次。如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
  • 匿名对象,在【调用方法】的时候,只能调用唯一一次。如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
  • 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】。强调:匿名内部类和匿名对象不是一回事!!!

猜你喜欢

转载自www.cnblogs.com/wurengen/p/12818265.html
今日推荐