Java教程

Java面向对象篇(内部类)

本文主要是介绍Java面向对象篇(内部类),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

概述

如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。

分类:
1. 成员内部类
2. 局部内部类(包含匿名内部类)

成员内部类的定义格式:
修饰符 class 外部类名称 {
    修饰符 class 内部类名称 {
        // ...
    }
    // ...
}

注意:内用外,随意访问;外用内,需要内部类对象。

==========================

成员内部类
如何使用成员内部类?有两种方式:
1. 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
2. 直接方式,公式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】

上代码

在外部类中定义内部类

public class Body {//外部类
    public class Heart{//成员内部类
        //内部类的方法
        public void beat(){
            System.out.println("我是内部类的方法");
            //成员内部类中可以直接调用外部类中的成员变量
            System.out.println("我的名字是"+name);
            System.out.println("我的名字是"+getName());
        }
    }
    private String name;//成员方法(外部类)

    public Body() {//空参
    }

    public Body(String name) {//实参
        this.name = name;
    }
    //外部类的方法
    public void method(){
        System.out.println("外部类方法");
        //可以在外部类中创建内部类对象并调用内部类方法
//        Heart heart = new Heart();
//        heart.beat();
        //或者直接匿名对象调用
        new Heart().beat();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试

public class Demo01InnerClass {
    public static void main(String[] args) {
        //使用成员内部类:
        //1、间接方式:通过外部类方法使用内部类
        Body body = new Body();
        body.method();
        System.out.println("=============");
        //2、直接方式:公式:【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
        Body.Heart bh = new Body().new Heart();
        bh.beat();
    }
}

内部类的同名变量访问

创建类

//内部类方法中访问外部类成员变量:外部类名称.this.外部类成员变量
public class Outer {
    int age = 10;//外部类成员变量
    public class inter{
        int age = 20;//内部类成员变量
        public void methodAge(){//内部类成员方法
            int age = 30;//内部类局部变量
            System.out.println(age);//访问局部变量
            System.out.println(this.age);//访问内部类成员变量
            System.out.println(Outer.this.age);//访问外部类成员变量
        }

    }
}

测试类

public class Demo02InterClass {
    public static void main(String[] args) {
        //使用内部类
        Outer.inter oi = new Outer().new inter();
        oi.methodAge();
    }
}

局部内部类

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

定义格式:
修饰符 class 外部类名称 {
    修饰符 返回值类型 外部类方法名称(参数列表) {
        class 局部内部类名称 {
            // ...
        }
    }
}

小节一下类的权限修饰符:
public > protected > (default) > private
定义一个类的时候,权限修饰符规则:
1. 外部类:public / (default)
2. 成员内部类:public / protected / (default) / private
3. 局部内部类:什么都不能写

代码篇:

创建局部内部类:

public class Outer {
    public void methodOuter(){
        //局部内部类在方法中定义
        System.out.println("外部类方法");
        class Inter{
            int age = 20;
            public void methodInter(){
                System.out.println("局部内部类方法"+age);
            }
        }
        //局部内部类在方法中创建对象,并调用方法
        Inter inter = new Inter();
        inter.methodInter();
    }
}

测试类

public class DemoMain {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.methodOuter();
    }
}

局部内部类的final问题

创建类

public class MyOuter {
    int age = 20;//final不写也行,但是外部成员变量值不能便,方便内部类使用
//    final int age = 20;
    public void methodMyOuter(){
        class MyInter{
            public void methodMyInter(){
                System.out.println(age);//在局部内部类中可以访问外部类的成员方法
            }
        }
        MyInter myinter = new MyInter();
        myinter.methodMyInter();
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        MyOuter o = new MyOuter();
        o.methodMyOuter();
    }
}

匿名内部类【重点】

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。

匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {
    // 覆盖重写所有抽象方法
};

对格式“new 接口名称() {...}”进行解析:
1. new代表创建对象的动作
2. 接口名称就是匿名内部类需要实现哪个接口
3. {...}这才是匿名内部类的内容

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

代码篇

接口

public interface MyInterface {
    public void Method1();
    void Method2();

}

接口实现类

public class MyInterImpl implements MyInterface{
    @Override
    public void Method1() {
        System.out.println("覆盖重写1");
    }

    @Override
    public void Method2() {
        System.out.println("覆盖重写2");
    }
}

测试类

public class DemoMain {
    public static void main(String[] args) {
        //匿名内部类
        MyInterface obj = new MyInterface() {
            @Override
            public void Method1() {
                System.out.println("覆盖重写Method1方法");
            }

            @Override
            public void Method2() {
                System.out.println("覆盖重写Method2方法");

            }
        };
        obj.Method1();
        obj.Method2();
        System.out.println("===============");

        //匿名内部类匿名对象
        new MyInterface(){

            @Override
            public void Method1() {
                System.out.println("覆盖重写1");
            }

            @Override
            public void Method2() {
                System.out.println("覆盖重写2");

            }
        }.Method1();
        new MyInterface(){

            @Override
            public void Method1() {

                System.out.println("覆盖重写1");
            }

            @Override
            public void Method2() {
                System.out.println("覆盖重写2");

            }
        }.Method2();
    }
}

类作为成员变量类型

案例:创建一个英雄类,成员方法有姓名,年龄,武器。其中,武器单独是一个类。

英雄类

public class Hero {
    private String name;
    private int age;
    private Weapon weapon;

    public Hero() {
    }

    public Hero(String name, int age, Weapon weapon) {
        this.name = name;
        this.age = age;
        this.weapon = weapon;
    }
    public void Show(){
        System.out.println("我是:"+getName()+",今年"+getName()+"岁。"+"我使用:"+weapon.getCode());
    }

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

    public Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}

武器类

public class Weapon {//武器类
    private String code;

    public Weapon() {
    }

    public Weapon(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

测试类

public class DemoMain {
    public static void main(String[] args) {
        //创建一个英雄对象
        Hero hero = new Hero();
        hero.setName("孙悟空");
        hero.setAge(550);
        //创建一个武器对象
        Weapon weapon = new Weapon();
        weapon.setCode("金箍棒");
        hero.setWeapon(weapon);
        hero.Show();
    }
}

接口作为成员变量类型

案例:创建一个英雄类,成员方法有:姓名,技能。其中,技能使用接口实现。

英雄类

public class Hero {
    private String name;//姓名
    private Skill skill;//技能

    public Hero() {
    }

    public Hero(String name, Skill skill) {
        this.name = name;
        this.skill = skill;
    }
    public void showGame(){
        System.out.println("姓名"+getName()+"触发技能:");
//        skill.method();
        skill.method();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Skill getSkill() {
        return skill;
    }

    public void setSkill(Skill skill) {
        this.skill = skill;
    }
}

接口

public interface Skill {
    public void method();
}

接口实现类

public class SkillImpl implements Skill{
    @Override
    public void method() {
        System.out.println("实现接口抽象方法覆盖重载");
        System.out.println("触发技能:啪啪啪");
    }
}

测试类

public class DemoGame {
    public static void main(String[] args) {
//        //创建实现类对象
//        SkillImpl skillImpl = new SkillImpl();
//        //创建对象
//        Hero hero = new Hero();
//        hero.setSkill(skillImpl);
//        hero.setName("哪吒");
//        hero.showGame();


        //方法二
//        //创建接口匿名内部类,写入技能方法
//        Skill skill = new Skill() {
//            @Override
//            public void method() {
//                System.out.println("触发技能:当当当");
//            }
//        };
//                //创建对象
//        Hero hero = new Hero();
//        hero.setName("哪吒");
//        hero.setSkill(skill);
//        hero.showGame();

        //方法三:匿名内部类匿名对象
        Hero hero = new Hero();
        hero.setName("哪吒");
        hero.setSkill(new Skill() {
            @Override
            public void method() {
                System.out.println("触发技能:咚咚咚咚");
            }
        });
        hero.showGame();
        };
    }

接口作为方法的参数或者返回值

import java.util.ArrayList;
import java.util.List;

/*
java.util.List正是ArrayList所实现的接口。
 */
public interface DemoInterface {
    public static void main(String[] args) {
        //左边是接口名称,右边是实现类名称,这就是多态的写法
        List<String> list = new ArrayList<>();
        List<String> li = adds(list);
        for (int i = 0; i < li.size(); i++) {
            System.out.println(li.get(i));
        }

    }

    public static List<String> adds(List<String> list){
        list.add("张三");
        list.add("李四");
        list.add("王二");
        list.add("麻子");
        return  list;
    }
}

本章节已结束,喜欢的小伙伴可以在评论区一起交流,谢谢支持!

这篇关于Java面向对象篇(内部类)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!