首页 > 编程语言 >Java的内部类区别

Java的内部类区别

时间:2023-11-13 21:22:17浏览次数:29  
标签:Java 内部 区别 void System sex println public out

一.成员内部类

成员内部类是创建在一个类的中的,它的位置和此类的属性是同一级的,可以说是它的成员类,或成员属性

特点:

成员内部类可以访问外部类的静态属性,也可以访问其外部非静态属性

类方法如果要去访问其成员内部类的方法,还是需要才此类中去创建对象,实例化成员内部类,然后调用

在启动主方法调用成员内部类中的方法的时候,需要先实例化外部类对象,再实例化外部类的成员变量,从而拿到成员内部类对象

代码:

class Person{
    private static String name="张三";
    private int age=18;

    class sex{
        private String sex="boy";
        public void sayName(){
            System.out.println("我的名字是:"+name);
            System.out.println("年龄是:"+age);
        }
    }

    public void saySex(){
        System.out.println("性别是:"+new sex().sex);
    }

}

 

成员内部类:

    class sex{
        private String sex="boy";
        public void sayName(){
            System.out.println("我的名字是:"+name);
            System.out.println("年龄是:"+age);
        }
    }

 

实例化成员内部类的方式:

        //成员内部类的实例化方式
        Person.sex sex = new Person().new sex();

 

需要先实例化外部类,然后再实例化成员内部类

成员内部类的方法调用:

//内部类输出外部类的属性
        sex.sayName();

 

二.静态内部类

见名知意,这种内部类肯定是有static所修饰的成员内部类

特点:

类中的方法可以访问外部类的静态属性和方法,但是不能访问非静态的属性和方法

其它的特点和成员内部类一样

代码:

class Person{
    private static String name="李四";
    private int age=16;

    public static class sex{
        private String sex="girl";
        public void sayName(){
            System.out.println("我的名字是:"+name);
//错误调用,不能调用非静态的属性 System.out.println("年龄是:"+age);
        }
    }
    public void saySex(){
        System.out.println("性别是:"+new sex().sex);
    }
}

 

静态内部类:

    public static class sex{
        private String sex="girl";
        public void sayName(){
            System.out.println("我的名字是:"+name);
//错误调用,不能调用非静态的属性 System.out.println("年龄是:"+age);
        }
    }

 

这里主要是注意静态内部类的特点,就是外部类中的非静态属性是不能被访问的

静态内部类的实例化方法:

        //静态内部类的实例化方式
        Person.sex sex = new Person.sex();

 

三.局部内部类

局部内部类是定义在类的局部的类,局部指的是方法内部或代码块内部

特点:

局部内部类可以访问外部类的静态方法和属性,也可以访问非静态的方法和属性

这种类只能在局部使用,实例化的生命周期也在方法中,是出不了方法作用域的,所以叫局部内部类

代码:

class Person{
    private static String name="王五";
    private int age=12;
    public void saySex(){
        class sex{
            private String sex="girl";
            public void sayName(){
                System.out.println("我的名字是:"+name);
                System.out.println("年龄是:"+age);
            }
        }
        System.out.println("性别是:"+new sex().sex);
        new sex().sayName();
    }
}

 

方法中的局部内部类:

    public void saySex(){
        class sex{
            private String sex="girl";
            public void sayName(){
                System.out.println("我的名字是:"+name);
                System.out.println("年龄是:"+age);
            }
        }
        System.out.println("性别是:"+new sex().sex);
        new sex().sayName();
    }

 

实例化局部内部类只能在方法中,声明局部内部类的空间就是它的生命周期

四.匿名内部类

在类中定义的一个没有类名只有类体的类

这一类的定义多发生在抽象类和接口中,对于不同的实现方法的方式来构造不同的类

但是这些类都有一个很明显的特点,它们只是类名和方法体不一样,所以为了不频繁的创建类,我们可以直接使用匿名内部类,不创建类,在需要使用的地方,直接实现此类

第一种方式:普通类定义匿名内部类

普通的类内部的方法都是实现过的,如果使用原方法,则直接使用super关键字来指向父级,

如果需要重写方法那么就在匿名内部类中找到那个方法然后重写,然后通过实例化对象调用

普通类:

class Animal{
    private static String animal;
    private String kins;
    public void saySing(){
        System.out.println("动物在唱歌");
    }
}

 

匿名内部类的定义方式:

Animal animal=new Animal() {
            @Override
            public void saySing() {
                super.saySing();
            }
        };

 

如上:使用匿名内部类可以选择重写已经实现的方法,或者不重写,默认是不重写,如果重写就在方法体中重写代码段

根据上面可以看出匿名内部类把实例化对象和实现方法是写在一起了的,所以使用的使用直接使用对象调用就可以了

匿名内部类的使用:

animal.saySing();

第二种方式:抽象类定义匿名内部类

抽象类是以abstract关键字定义的类,它的内部可以有实现的方法,也可以有未实现的抽象方法

这类的的匿名内部类必须要实现未实现的方法,不然是定义不成功的

抽象类:

abstract class Person{
    private static String name="王五";
    private int age=12;
    public abstract void sayHigh();
    public void saySex(){
        class sex{ 
            public void sayName(){
                System.out.println("我的名字是:"+name);
                System.out.println("年龄是:"+age);
            }
        }
    }
}

 

匿名内部类的定义:需要实现未实现的抽象方法

Person person = new Person(){
            @Override
            public void sayHigh() {
                System.out.println("身高为:181cm,体重为:68kg");
            }
            @Override
            public void saySex() {
                super.saySex();
            }
        };

 

这里重写了抽象方法sayHigh()因为它是抽象方法必须要实现,二另外一个方法则不需要实现,或者可以重写,我没有重写,而是直接使用父类的,还可以不用管他,默认使用父类

这也是实例化和方法实现一起定义的,所以调用方法时,也是对象 . 方法

匿名内部类使用:

        person.sayHigh();
        person.saySex();

 

第三种方式:使用接口定义匿名内部类

由于接口中只会存在未实现的抽象方法,所以使用结构定义的匿名内部类时,需要把接口中所用的方法都实现一遍

接口部分:

public interface TestClassInterface {
    void say();
    void sing();

}

 

主方法中定义匿名内部类:

       TestClassInterface tci=new TestClassInterface(){
            @Override
            public void say() {
                System.out.println("有人在说话");
            }

            @Override
            public void sing() {
                System.out.println("有人在唱歌");
            }
        };

 

需要实现接口中所有的方法,然后使用实例化对象去调用这些在主方法中实现的方法

匿名方法的使用:

依旧对象名 .  方法

tci.say(); 
tci.sing();

 

总结:

Java之所以有那么多内部类,原因在于提升了封装的隐藏细节的特点

我们已经讲过了,面向对象的三大特征继承,封装,多态,封装需要隐藏大量的实现细节,对于一个类的集合不能使用 private 关键字实现封装,所以很容易被发现类中的实现

但是内部类时完全隐藏的,它可以对所用外部类拥有访问权限,还能隐藏对这些属性的实现细节,这使得很大程度上提升了封装的特点

五.组合类

观点:组合优于继承

组合就是把一个类当作另一个类的成员属性

当使用继承的时候,两个类中有相同的方法名,很显然,继承中会重写这个方法,所以方法名相同的只能有一个存在,要么是父类的,要么是子类重写的

在组合中,两个两个相同的类名可以同时存在,只是调用的方式不一样,在自己类中的方法直接调用,组合的类需要使用组合类名 . 方法

组合类代码:

class Dog{
    //组合类:类作为此类的属性
    private Animal animal;

    public Dog(Animal animal) {
        this.animal = animal;
    }

    public void say(){
        System.out.println("狗再叫~~");
        animal.saySing();
        System.out.println(animal.getKins());
    }
}

 

这里组合了Animal这一个类,其中也使用了它的方法和属性

Animal类:

class Animal{

    private static String animal="动物";
    private String kins="animal";

    public static String getAnimal() {
        return animal;
    }

    public static void setAnimal(String animal) {
        Animal.animal = animal;
    }

    public String getKins() {
        return kins;
    }

    public void setKins(String kins) {
        this.kins = kins;
    }

    public void saySing(){
        System.out.println("动物在唱歌");

    }
}

 

使用组合类:

Dog dog = new Dog(new Animal());
dog.say();

 

由于Animal是它的属性类,所以需要传入一个Animal对象进去,否则会形成空指针异常

简单讲,组合就是讲类当作属性然后再另外一个类中一起使用,当然,使用被组合的类需要传入一个这个类的实例对象

 在Java中,组合类(Composition)是一种重用类代码的形式,它允许在一个类中使用已有的类的实例来定义新的类。这种组合的方式通常是将一个或多个现有类的对象嵌入到新类中,新类可以通过这些对象来使用现有类的功能

组合类也可以创建对象作为对象字段去创建新的组合类,这种过程被称为多级封装。同时,对于对象字段和非对象字段,我们也可以规定它们的访问权限,这被称为二次封装。

标签:Java,内部,区别,void,System,sex,println,public,out
From: https://www.cnblogs.com/5ran2yl/p/17827621.html

相关文章

  • JavaWeb--在IDEA中部署Maven Web项目
    Web的项目结构:1、MeavenWeb项目结构:开发中的项目在IDEA中创建Maven项目1、使用骨架 2、不使用骨架 1、添加打包方式为war 2、补齐缺失的目录2、部署的JaveWeb项目结构:开发完成,可以部署的项目......
  • 解决java中0.1+0.2=0.30000000000000004的问题
     前言在现实中我们都知道:0.1+0.2=0.3但是在程序中会出现这样的结果:0.1+0.2=0.30000000000000004原因对于0.1来说,其本质是1/10,那么若你用二进制表示它们,然后除的话,是这样的:1/1010,然而这一个是除不尽的,是无穷循环。 ===>0.000110011001100110011001100110011........
  • Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmedia
    下列关于Vue的描述错误的是()A当给某个组件修改某个值时,该组件不会立即重新渲染BVue内部使用原生Promise.then、MutationObserver和setImmediate实现异步队列,不会采用setTimeout(fn,0)C$nextTick()返回一个Promise对象D$nextTick()可以配合async/await使用正确答案:B官......
  • 20 个好用的一行 Java代码
    今天分享给大家20个令人惊叹的Java一行代码,让你们的工作更轻松。一起来看看吧!1.获取浏览器Cookie的值使用document.cookie来获取Cookie的值。2.将RGB转换为十六进制3.复制到剪贴板使用navigator.clipboard.writeText轻松将任何文本复制到剪贴板上。4.检查日期是否......
  • JavaSE DataStructure
    JavaSEDataStructureListArrayListArrayListDemo1点击查看代码importjava.util.ArrayList;importjava.util.Collection;importjava.util.Iterator;classArrayListDemo1{publicstaticvoidmain(String[]args){Collection<String>list=newA......
  • Java文件处理(一):创建文件、遍历文件夹、删除文件/文件夹
    本篇以代码为核心,在实践中自学吧年轻人~非常好迭代作业,爱来自BUAAFile对象要进行文件处理肯定需要File类啦。File的实例是一个实例(?),但是可以链接到本地的文件、文件夹,并对它们进行操作。从下面的一些示例中可以看到,同一份本地文件可以拥有多个File对象;同时,构造一个File对象......
  • selenium和playwright的区别和使用方法
    Selenium和Playwright都是自动化测试工具,可以用于模拟用户操作、执行测试脚本、验证网站功能和性能等。它们的主要区别在于实现方式和功能特性。1.实现方法Selenium是基于浏览器驱动的自动化测试工具,支持多种编程语言和多种浏览器。Selenium通过启动浏览器驱动程序(如Chrome......
  • java里junit 单元测试、注释(入门)
    什么是Junit单元测试?JUnit单元测试是指使用JUnit框架编写的针对代码中小的、独立的模块(通常是方法或者类)的测试。在JUnit中,您可以使用断言来验证代码的行为是否符合预期,以及使用注解来标记测试方法、测试套件等。执行单元测试可以帮助验证代码是否满足特定的业务需求和技术......
  • java中一些空判断|ObjectUtils
    为什么用ObjectUtils?在java中判断对象是否为null,常常不止判断对象是否为null,如果对象是集合,数组,字符串等等特殊类型,还需要检查是否为空(元素个数为0或者长度为0)ObjectUtils.isEmpty可以简化下面这些问题(当然,你使用的是spring)对象为null。对象是数组,且长度为0。对象是集合(Coll......
  • 入门级throw与throws的区别
    throw与throws区别一:    throw与throws的区别二:    throw与throws的区别三:   throw与throws的区别四:throw,如果执行了,那么一定是抛出了某种异常了,安生throws表示可能出现,但不一定。......