内部类和外部类的区别和联系

其实外部类和内部类是一个相对的定义
类A中有类B,那么类A自然就是外部类了,类B就是内部类。


外部类的访问权限只有两种:public和(default)。
但是内部类因类型不同所以对应的访问权限也不一样。


内部类可以使用外部类的任何变量和方法,但是外部类必须要实例化内部类才可以使用内部类。
而且在实例化之前必须先创建一个外部类的实例。

不过也可以使用this来调用外部类和内部类的元素。


内部类分为成员内部类,匿名内部类、局部内部类和静态内部类。

  ① 成员内部类

  成员内部类其实就是最简简单单的那种内部类了,定义在一个类的内部。

public class MemInner {
    int num = 10;
    public static void main(String[] args) {
        MemInner mi = new MemInner();
        Inner in = mi.new Inner();
        System.out.println(in.num);
        in.systemOut();
    }
    public class Inner{
        int num = 9;
        public void systemOut(){
            System.out.println(num);
            System.out.println(MemInner.this.num);
        }
    }
}

  如果外部类想要调用内部类,先要实例化内部类相对的外部类,然后再实例化目标内部类,然后才能访问里面的成员变量和方法。

  并且如果想要访问内部类和外部类同名的成员变量或成员方法,需要按照以下格式访问:

外部类.this.成员变量

外部类.this.成员方法

  而且无论外部类的成员变量或成员方法的访问权限是什么,内部类统统都可以访问。

 

  ② 局部内部类

  局部内部类是定义在方法或者是一个作用域上面的类,它和成员内部类的区别就在于局部内部类的访问权限仅在定义它的这个方法或者作用域里面(访问范围缩小)。

public class AreaInner {
    int num = 9;
    public static void main(String[] args) {
        AreaInner ai = new AreaInner();
        ai.Inner();
    }
    public void Inner(){
        String name = "黄花大闺女";
        class AInner{
            void call(){
                System.out.println(num);
                System.out.println(name);
            }
        }
        AInner an = new AInner();
        an.call();
    }
}

  就像是main()函数调用不了方法中的局部变量一样,如果想要在外部类实例化局部内部类,首先要在这个方法或者作用域里面提前实例化此内部类,然后在外部类调用其方法或者作用域的时候,就可以真正为这个内部类提供资源空间。

 

  ③ 匿名内部类

  匿名内部类在用作监听器的时候是一个非常方便的写法,而且匿名内部类有两个特点:无构造器,不可使用static等限定词。

buttons[0].addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
              
     });

  使用匿名内部类之后就不需要在外部类重新实例化了,方便好用。

 

  ④ 静态内部类

  静态内部类跟成员内部类的区别就在于有没有"static"修饰,然后因为是静态类,所以要能访问的只有外部类中被static修饰过的成员变量或者方法。

public class StaticInner {
    int num = 9;
    static String name = "黄花大闺女";
    Inner i = new Inner();
    static class Inner{
        void call(){
            System.out.println(num);  //会报错
            System.out.println(name);
        }
    }
}

  在没有外部类的情况下是可以直接创建静态内部类实例的,但是如果要使用外部类的非静态成员变量或成员方法,还是需要创建外部类实例才可以使用。

 

  补充:内部类小结(参考自https://www.nowcoder.com/test/question/done?tid=17994589&qid=112853#summary)

-|内部类

  -|静态内部类:不可访问外部的非静态资源

    -|但是可以有public static abstract class Demo

  -|成员内部类:可以访问外部所有资源,但是本身内部不可有静态属性(因为自己本身就需要依靠外部类的实例化)

  -|局部内部类:不可被访问修饰符和static修饰,只能访问final变量和形参

    -|局部静态内部类:在外部类的静态方法中

    -|局部内部类:在外部类的一般方法中

  -|匿名内部类:没有构造器,没有静态资源,无法被访问修饰符、static修饰;只能创建匿名内部类的一个实例;创建的时候一定是在new的后面

 

 

本人的这篇文章只是很片面的说一下而且,十分推荐这一篇文章:https://www.cnblogs.com/dolphin0520/p/3811445.html

参考:

https://www.cnblogs.com/wcyBlog/p/3918753.html

https://www.cnblogs.com/dolphin0520/p/3811445.html

 

    

转载于:https://www.cnblogs.com/NYfor2018/p/9466476.html

<think>好的,用户想了解“类外定义”“线性表外定义”的区别。首先,我需要明确这两个术语的具体含义,因为它们在编程数据结构中可能有不同的解释。 首先,“类外定义”通常出现在面向对象编程的上下文中。比如在C++中,类的成员函数可以在类内部声明,然后在类外部进行定义。这有助于分离声明实现,提高代码的可读性维护性。例如,在类内部声明一个函数,然后在.cpp文件中实现它,这样就是类外定义。需要确认用户是否指的是这种情况。 接下来是“线性表外定义”。这里的“线性表”是数据结构中的一个基本概念,比如数组、链表、栈、队列等。但“线性表外定义”这个术语并不常见,可能是用户表述上的误差。可能是指线性表的不同实现方式,比如顺序存储(数组)链式存储(链表)的区别。或者是线性表与其他数据结构(如树、图)的外部操作差异?需要进一步推测用户意图。 用户可能混淆了术语,比如将“外部定义”与某种数据结构操作联系起来。例如,线性表的操作是否在结构外部定义,如通过函数操作,而不是内部方法。比如在C语言中,线性表的操作通常通过外部函数实现,而不是类的方法(因为C不是面向对象的)。而在C++中,可能会将操作封装在类内部作为成员函数。这种情况下,“类外定义”“线性表外定义”可能分别指不同语言中的实现方式。 需要验证这些可能性。首先,类外定义在C++中是明确的,成员函数在类外定义时需要使用作用域解析运算符。而线性表作为数据结构,其操作在不同语言中的实现方式不同。例如,在C中用结构体函数,而在C++中可能用类封装。因此,“线性表外定义”可能指的是在数据结构外部实现的函数,而非类成员函数。 总结区别: 1. **类外定义**:面向对象编程中,类成员函数在类外部实现,保持接口与实现分离。 2. **线性表外定义**:可能指线性表的操作在数据结构外部通过独立函数实现,而非封装在类内部。 需要进一步确认用户的具体上下文,但根据常见情况,这样的解释应该能帮助用户理解两者的区别。</think>### 类外定义 vs 线性表外定义的区别 #### 1. **类外定义(面向对象编程中的概念)** - **定义**:在面向对象编程(如C++)中,类的成员函数可以在类声明**外部**单独定义,需通过作用域解析运算符`::`标明所属类。 - **目的**:实现**接口与实现的分离**,增强代码可维护性。 - **示例**: ```cpp // 类内声明 class MyClass { public: void myFunction(); // 类内声明 }; // 类外定义 void MyClass::myFunction() { // 具体实现 } ``` #### 2. **线性表外定义(数据结构实现中的概念)** - **定义**:线性表(如顺序表、链表)的**操作函数**(如插入、删除)在数据结构**外部**独立实现,而非封装在类/结构体内部。 - **典型场景**:在非面向对象语言(如C语言)中,线性表通过结构体定义数据,操作函数独立存在。 - **示例**: ```c // 结构体定义线性表 typedef struct { int data[100]; int length; } SeqList; // 外部定义插入函数 void insert(SeqList* list, int index, int value) { // 具体实现 } ``` #### 3. **核心区别** | **维度** | **类外定义** | **线性表外定义** | |----------------|----------------------------------|--------------------------------| | **应用领域** | 面向对象编程(类成员函数) | 数据结构实现(操作函数) | | **语法依赖** | 需作用域解析运算符`::`(如C++) | 无需特殊语法(如C语言) | | **封装性** | 仍属于类的一部分,受访问控制限制 | 完全独立,直接操作数据结构 | | **典型语言** | C++、Java(外部方法需`static`) | C、早期无类语言 | #### 4. **实际意义** - **类外定义**:通过分离声明与实现,优化代码结构,便于团队协作。 - **线性表外定义**:体现数据与操作的解耦,适用于非面向对象设计模式。 #### 5. **扩展说明** 若在C++中实现线性表,两种方式可能结合: ```cpp class LinkedList { private: Node* head; public: void insert(int index, int value); // 类内声明 }; // 类外定义成员函数 void LinkedList::insert(int index, int value) { // 实现代码 } ``` 此时,类的成员函数通过**类外定义**实现,而操作仍封装在类内部,与C语言的外部函数有本质区别。 如需进一步探讨具体编程场景,可提供更多上下文信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值