栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

面向对象通识19(内部类)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

面向对象通识19(内部类)

面向对象通识19(内部类)

定义在类体中定义的类(包含内部类的类被称为外部类)

基本语法和外部类相同,区别:

  • 可以使用以下三种修饰符

    • 内部类可以用static修饰,表明该内部类为外部类的一个实例

    • 可以用private修饰,表明该内部类只能在外部类中被访问

    • 可以用protected修饰,表名该内部类能在其外部类中被访问,也可以被其子类访问

  • 非静态内部类不能拥有静态成员

  • 内部类可以直接访问外部类的私有成员,但static内部类不能直接访问外部类的非static成员

意义
  • 当某个类及其实例必须要依附于别的类的存在而存在,就需要定义该类的内部类(内部接口、内部枚举)
  • 内部类可以提供更好的封装,可以通过private修饰让它完全隐藏于外部类
特性

内部类可以直接访问外部private的成员变量

public class Cow {
    private double weight;
    public class CowLeg{
        public void test(){
            System.out.println("test方法");
            //直接访问外部类的private成员变量
            System.out.println("weight成员变量"+weight);
        }
    }
}
内部类区分变量

举例:

public class Dog {
    private int len=20;
    private class DogTail{
        private int len=200;
        public void info(){
            System.out.println("len:"+len);
        }
    }
    static DogTail dt;

    public static void main(String[] args) {
        dt=new DogTail();//编译错误,static方法访问非static内部类
    }
}

内部类可以直接访问外部类的成员变量,但如果内部类的方法、内部类的成员变量与外部类的成员变量重名时,就需要区分。

class Dog1{
    protected int len=2;
}
public class Dog extends Dog1{
    private int len=20;
    private class DogTail{
        private int len=200;
        public void info(){
            int len=2000;
            System.out.println("len:"+len);
            //就近访问局部变量
            System.out.println("len:"+this.len);
            //this.引用,限定访问当前类的实例变量
            System.out.println("len:"+Dog.this.len);
            //外部类.this.引用,限定访问当前类的外部类的实例变量
            System.out.println("len:"+Dog.super.len);
            //外部类.super.引用,限定访问当前类的外部类的父类的实例变量
        }
    }
    static DogTail dt;
    public void test(){
        //实例方法调用非静态内部类
        dt=new DogTail();
        dt.info();
    }

    public static void main(String[] args) {
        Dog d =new Dog();
        d.test();
    }
}

在外部类以外使用静态内部类
  • 基本上使用内部类与试用版其他类没什么区别,唯一注意,static成员不能使用非static内部类创建实例

(如果只是声明变量,不算主动使用)

  • 在外部类以外使用静态内部类

    该内部类一定不能用private修饰;

    • 声明变量:外部类.静态内部类 变量名

    • 创建对象:new 外部类.静态内部类构造器

    • 调用方法:外部类.静态内部类.

    • 派生子类:extands 外部类.静态内部类(注意构造器调用)

      综上,把外部类名当做静态内部类的包名调用即可

举例:

public class StaticOuter {
    //定义内部类
    public static class Inner {
        private int age;

        public Inner(int age) {
            this.age = age;
        }

        public void inTest() {
            System.out.println("静态内部类的测试方法");
        }

        public static int sum(int a, int b) {
            return a + b;
        }

        @Override
        public String toString() {
            return "Inner[age=" + this.age + "]";
        }
    }
}
public class InnerTest {

    public static void main(String[] args) {
        StaticOuter.Inner nm=new StaticOuter.Inner(4);//声明变量、创建对象
        StaticOuter.Inner.sum(2,3);//调用方法
        nm.inTest();
    }
}
class Outer extends StaticOuter.Inner{
//派生子类
    public Outer() {
        super(3);
    }
}
在外部类使用非静态的内部类
  • 内部类:也叫寄生类

    • static内部类的实例,要寄生在外部类本身之中

      • 只要用到该内部类,外部类就会被自动初始化

      • 非static内部类的实例,要寄生在外部类的实例之中

  • 外部类:也叫宿主类

  • 在外部类使用非静态的内部类:

    • 声明变量:外部类.静态内部类 变量名

    • 创建对象:宿主.new 费静态内部类构造器

      • 所谓宿主就是用外部类创建的对象名称

        或者:new 外部类构造器.new 内部类构造器

        第一个new的目的仅仅是为了得到宿主对象

    • 访问类变量(只能是常量):外部类.非静态内部类.类常量

    • 派生子类:extands 外部类.非静态内部类

      重点在子类构造器第一行,必须用到的语法:

      宿主.super(参数)

非静态内部类(包括其子类)的实例的素质是外部类的实例,因此必须由开发者创建外部类实例作为宿主。

举例:

public class inClass {
class B {
        public void test() {
            System.out.println("仅仅是一个非静态的内部类");
        }
}
public class InnerTest {
	inClass.B in;
    inClass A=new inClass();
    //创建对象:宿主.new非静态内部类的构造器(参数);此处的A为宿主对象
    in=A.new B();
    //第一个new是主动创建一个宿主对象
    inClass.B iin=new inClass().new B(); 
}
class Outer1 extends inClass.B{
    public Outer1(){
        new inClass().super();
    }
}
局部内部类

局部内部类放在方法中定义

局部内部类也只能用final修饰

(just like 局部变量)

public class LocalInner {
    public void a(){
        //局部内部类
        class In{

        }
    }
    public void b(){
        //局部内部类
        class In{

        }
    }
}

局部内部类只能在所定义的方法中使用,局限性很强,所以用的很少

局部内部类的类文件名为外部类$N内部类.class

匿名内部类

(很常用,普遍存在于安卓开发)

匿名内部类是没有名字的类,只能在创建的时候立即创建实例,以后不能复用该类

语法:
new 父类构造器(参数)|接口(){
    //类体部分
   //一般的,类体部分就是实现抽象方法,因为没有类名,所以可以创建四大成员但是无法调用
}

从上述语法可以看出:

  • 匿名内部类必须要显示集成一个父类或者实现一个接口,不能同时实现多个接口。

  • 不能实现父类的同时实现接口

  • 匿名内部类不能是抽象类,因此必须实现抽象接口或是抽象父类中的所有抽象方法

  • 可以定义出了构造器以外的四大成员,因为构造器的名字要和类名相同

举例:

public class 匿名颞部类 {
    public static void main(String[] args) {
        animal an=new animal(2.3)
        //向上转型:此处用animal的子类的实例赋值
        {
            @Override
            public void taste(){
                System.out.println("bad");
            }
            public void food(){
                System.out.println("为匿名内部类创建方法");
            }
        };//匿名内部类的类体
        an.taste();
        an.walk();
        //an编译时的类型是animal,不存在food方法
        Printable p=new Printable() {
            //类体部分只要实现抽象方法即可
            @Override
            public void print() {
                System.out.println("打印数据");
            }

            @Override
            public void inputDta() {
                System.out.println("输入数据");
            }
        };
        p.print();
        p.inputDta();
    }
}
abstract class animal{
    private double weight;
    animal(double weight){
        this.weight=weight;
    }
    public void walk(){
        System.out.println("Just walk.");
    }
    public abstract void taste();
}
interface Printable{
    //默认修饰符public和abstract
    void print();
    void inputDta();
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/985347.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号