• day1120211213


    湖南

    面向对象5 接口 面向接口编程 内部类

    1.接口

    1.1接口的概念

    与之前学习过的抽象类一样,接口( Interface )在Java中也是一种抽象类型,接口中的内容是抽象形成的需要实现的功能,接口更像是一种规则和一套标准.

    1.2接口格式

    1.3接口的特点

    1. 通过interface关键字来定义接口
    2. 通过implements让子类来实现接口
    3. 接口中的方法全部都是抽象方法(JAVA8)
    4. 可以把接口理解成一个特殊的抽象类(但接口不是类!!!)
    5. 类描述的是一类事物的属性和方法,接口则是包含实现类要实现的方法
    6. 接口突破了java单继承的局限性
    7. 接口和类之间可以多实现,接口与接口之间可以多继承
    8. 接口是对外暴露的规则,是一套开发规范
    9. 接口提高了程序的功能拓展,降低了耦合性

    2.练习

    2.1创建接口

    创建包:cn.tedu.inter
    创建接口:Inter.java

    package cn.tedu.inter;
    /*本接口用于创建接口测试*/
    /*1.我们通过interface关键字来定义接口*/
    public interface Inter {
        /*2.接口中可以定义普通方法吗?--不可以!*/
        //public void eat(){}
        /*3.接口中可以定义抽象方法吗?--可以,接口中的方法都是抽象方法!*/
        public abstract void eat();
        public abstract void play();
    }
    

    2.2创建接口实现类

    创建包:cn.tedu.inter
    创建接口实现类:InterImpl.java

    package cn.tedu.inter;
    /*本类作为Inter接口的实现类*/
    /*1.实现类如果想要实现接口定义的功能,需要与接口建立实现关系
    * 通过关键字implements来建立实现类 实现 接口的关系*/
    /*2.1 方案一:如果实现类与接口建立实现关系以后
    可以选择不实现接口中的抽象方法,把自己变成一个抽象类*/
    //abstract public class InterImpl implements Inter{//方案一
    /*2.2方法二:如果实现类与接口建立实现关系以后
    * 还可以选择实现接口中的所有抽象方法,把自己变成一个普通子类*/
    public class InterImpl implements Inter{
        @Override
        public void eat() {
            System.out.println("吃火锅");
        }
        @Override
        public void play() {
            System.out.println("玩代码");
        }
    }
    

    2.3创建接口测试类

    创建包:cn.tedu.inter
    创建接口实现类:InterTests.java

    package cn.tedu.inter;
    /*本类用于运行测试接口实现类*/
    public class InterTests {
        public static void main(String[] args) {
            /*接口可以实例化吗?--不可以!!!*/
            //Inter i = new Inter();
    
            //创建多态对象进行测试--不常用
            Inter i = new InterImpl();
            i.eat();
            i.play();
    
            //创建纯纯的接口实现类对象进行测试--推荐使用
            InterImpl i2 = new InterImpl();
            i2.eat();
            i2.play();
        }
    }
    

    3.接口的用法

    3.1接口之构造方法

    创建包:cn.tedu.inter2
    创建类:TestUserInter.java

    package cn.tedu.inter2;
    /**本类用于进一步测试接口的使用*/
    public class TestUserInter {
    	//5.创建入口函数main()
    	public static void main(String[] args) {
    		/**查看类的继承结构:Ctrl+O*/
    		Inter2 i = new Inter2Impl();
    	}
    }
    //1.创建接口
    interface UserInter{
        //2.测试接口中是否包含构造方法
        //public UserInter(){}
        /*1.接口里没有构造方法*/
    }
    
    //3.创建接口的实现类
    class UserInterImpl implements UserInter{
        //4.创建实现类的构造方法
        public UserInterImpl(){
            /*2.如果一个类没有明确指定它的父类,那么它默认继承顶级父类Object*/
            super();/*3.此处调用的父类的无参构造是Object的无参构造*/
            System.out.println("我是子实现类的无参构造");
        }
    }
    

    总结:接口是没有构造方法的
    如果一个类没有明确指定它的父类,那么它默认继承顶级父类Object,调用的super()是Object的无参构造

    3.2接口之成员变量

    package cn.tedu.inter2;
    /*本类用于进一步测试接口的使用*/
    public class TestUserInter {
        public static void main(String[] args) {
            //6.测试接口中的静态常量
            System.out.println(UserInter.age);//静态,因为可以被接口名直接调用
            //UserInter.age = 37;//final,因为值不可以被修改
        }
    }
    //1.创建接口
    interface UserInter{
        //5.测试接口中是否可以定义成员变量
        /*4.接口中的是静态常量,实际上的写法是public static final int age = 20;
        * 只不过接口中可以省略不写,会默认拼接,所以写成 int age = 20;也可以*/
        public static final int age = 20;
    }
    //3.创建接口的实现类
    class UserInterImpl implements UserInter{}
    

    总结:接口里没有成员变量,都是常量.所以,你定义一个变量没有写修饰符时,默认会加上:public static final

    3.3接口之成员方法

    package cn.tedu.inter2;
    /*本类用于进一步测试接口的使用*/
    public class TestUserInter {
        public static void main(String[] args) {
           UserInterImpl u = new UserInterImpl();
            u.eat();
            u.play();
        }
    }
    //1.创建接口
    interface UserInter{
        //7.测试接口中有抽象方法吗?
        /*5.接口中抽象方法的定义可以简写,会自动给方法拼接public abstract*/
        public abstract void eat();
        void play();
    }
    //3.创建接口的实现类
    class UserInterImpl implements UserInter{
        @Override
        public void eat() {
    		System.out.println("实现接口中的抽象方法1");	
        }
        @Override
        public void play() {
    		System.out.println("实现接口中的抽象方法2");
        }
    }
    

    总结:接口里的方法,默认都是抽象的,方法上会默认拼接public abstract.例如:public abstract void save()

    3.4接口的多继承多实现

    创建包:cn.tedu.inter2
    创建类:TestRelation.java

    package cn.tedu.inner2;
    import cn.tedu.inter.Inter;
    
    /*本类用于测试接口与类之间的复杂关系*/
    public class TestRelation {
        public static void main(String[] args) {
            //创建对象进行功能测试
            Inter3Impl i = new Inter3Impl();
            i.save();
            i.delete();
            i.update();
            i.find();
        }
    }
    
    //1.创建接口1
    interface Inter1{
        void save();//保存功能
        void delete();//删除功能
    }
    //2.创建接口22
    interface Inter22{
        void update();//更新功能
        void find();//查询功能
    }
    //3.创建接口1的实现类
    class Inter1Impl implements Inter1{
        @Override
        public void save() { }
        @Override
        public void delete() { }
    }
    
    //4.创建接口3,同时继承两个接口
    /*1.接口可以继承接口,并且可以多继承,多个接口之间用逗号隔开*/
    interface Inter3 extends Inter1,Inter22{ }
    
    //5.创建接口3的实现类
    /*2.接口与实现类是实现的关系,并且可以多实现,多个接口之间用逗号隔开
    * 对于Java中的类而言,遵循:单继承 多实现
    * 一个类只能有一个父类,但是一个类可以实现多个接口*/
    //class Inter3Impl implements Inter3{//写法1
    class Inter3Impl implements Inter1,Inter22{//写法2
        @Override
        public void save() {
            System.out.println("稍等...正在努力保存中...");
        }
        @Override
        public void delete() {
            System.out.println("删除成功!");
        }
        @Override
        public void update() {
            System.out.println("小二正在马不停蹄的更新~");
        }
        @Override
        public void find() {
            System.out.println("客官,马上就查询好啦,稍等一丢丢~");
        }
    }
    

    总结

    类与类关系

    继承关系,只支持单继承
    比如,A是子类 B是父类,A具备B所有的功能(除了父类的私有资源和构造方法)
    子类如果要修改原有功能,需要重写(方法签名与父类一致 + 权限修饰符 >= 父类修饰符)

    类和接口的关系

    实现关系.可以单实现,也可以多实现
    class A implements B,C{}
    其中A是实现类,B和C是接口,A拥有BC接口的所有功能,只是需要进行方法的重写,否则A就是抽象类

    接口与接口的关系

    是继承关系,可以单继承,也可以多继承
    interface A extends B,C{}
    其中ABC都是接口,A是子接口,具有BC接口的所有功能(抽象方法)
    class X implements A{}
    X实现类需要重写ABC接口的所有方法,否则就是抽象类
    class A extends B implements C,D{}
    其中A是实现类,也是B的子类,同时拥有CD接口的所有功能
    这时A需要重写CD接口里的所有抽象方法

    接口与抽象类的区别

    1. 接口是一种用interface定义的类型抽象类是一种用class定义的类型
    2. 接口中的方法都是抽象方法,还有默认方法与静态方法抽象类中的方法不做限制
    3. 接口中的都是静态常量抽象类中可以写普通的成员变量
    4. 接口没有构造方法,不可以实例化.抽象类有构造方法,但是也不可以实例化
    5. 接口是先天设计的结果,抽象是后天重构的结果
    6. 接口可以多继承,抽象只能单继承

    内部类

    1.内部类概述

    如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。
    就是把类定义在类的内部的情况就可以形成内部类的形式。
    A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待:

    1.2特点

    1. 内部类可以直接访问外部类中的成员,包括私有成员
    2. 外部类要访问内部类的成员,必须要建立内部类的对象
    3. 在成员位置的内部类是成员内部类
    4. 在局部位置的内部类是局部内部类

    1.3内部类入门案例

    创建包:cn.tedu.innerclass
    创建类:TestInner1.java

    package cn.tedu.innerclass;
    /*本类用作测试内部类的入门案例*/
    public class TestInner1 {
        public static void main(String[] args) {
            //3.创建内部类对象,使用内部类的资源
            /*外部类名.内部类名 对象名 = 外部类对象.内部类对象*/
            Outer.Inner oi = new Outer().new Inner();
            oi.delete();
            System.out.println(oi.sum);
            //4.调用外部类的方法--这样是创建了一个外部类的匿名对象,只使用一次
            new Outer().find();
        }
    }
    
    //1.创建外部类 Outer
    class Outer{
        //1.1创建外部类的成员变量
        String name;
        private int age;
        //1.2创建外部类的成员方法
        public void find(){
            System.out.println("Outer...find()");
            //6.测试外部类如何使用内部类的资源
            //System.out.println(sum);--不能直接使用内部类的属性
            //delete();--不能直接调用内部类的方法
            /*外部类如果想要使用内部类的资源,必须先创建内部类对象
            * 通过内部类对象来调用内部类的资源*/
            Inner in = new Inner();
            System.out.println(in.sum);
            in.delete();
        }
        //2.创建内部类Inner--类的特殊成员
        /*根据内部类位置的不同,分为:成员内部类(类里方法外)、局部内部类(方法里)*/
        class Inner{
            //2.1定义内部类的成员变量
            int sum = 10;
            //2.2定义内部类的成员方法
            public void delete(){
                System.out.println("Inner...delete()");
                //5.测试内部类是否可以使用外部类的资源
                /*结论:内部类可以直接使用外部类的资源,私有成员也可以!*/
                System.out.println(name);
                System.out.println(age);
                /*注意:此处测试完毕需要注释掉,否则来回调用
                * 会抛出异常StackOverFlowException栈溢出异常*/
                //find();
            }
        }
    }
    

    2.成员内部类

    2.1练习:被private修饰

    创建包:cn.tedu.innerclass
    创建类:TestInner2.java

    package cn.tedu.innerclass;
    /**本类用来测试成员内部类被private修饰*/
    public class TestInner2 {
    	public static void main(String[] args) {
    		/**怎么使用内部类Inner2的资源?*/
    		//4.创建内部类Inner2对象进行访问
    		//Outer2.Inner2 oi = new Outer2().new Inner2();
    		//oi.eat();
    		
    		/**如果Inner2被private修饰,无法直接创建对象该怎么办?*/
    		//7.创建外部类对象,间接访问私有内部类资源
    		new Outer2().getInner2Eat();
    	}
    }
    //1.创建外部类Outer2
    class Outer2{
    	//6.提供外部类公共的方法,在方法内部创建Inner2内部类对象,调用内部类方法
    	public void getInner2Eat() {
    		Inner2 in = new Inner2();//外部类可以访问内部类的私有成员
    		in.eat();
    	}
    	//2.1创建成员内部类Inner2
    	/**成员内部类的位置:类里方法外*/
    	//5.成员内部类,被private修饰私有化,无法被外界访问
    	private class Inner2{
    		//3.创建内部类的普通成员方法
    		public void eat() {
    			System.out.println("我是Inner2的eat()");
    		}
    	}
    }
    

    总结:成员内部类被Private修饰以后,无法被外界直接创建创建对象使用所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

    2.2练习:被static修饰

    创建包:cn.tedu.innerclass
    创建类:TestInner3.java

    package cn.tedu.innerclass;
    /**本类用来测试成员内部类被static修饰*/
    public class TestInner3 {
    	public static void main(String[] args) {
    		/**如何访问内部类的show()?*/
    		//4.创建内部类对象访问show()
    		//方式一:按照之前的方式,创建内部类对象调用show()
    		//Outer3.Inner3 oi = new Outer3().new Inner3();
    		//oi.show();
    		//方式二:创建匿名内部类对象访问show()
    		//new Outer3().new Inner3().show();
    		
    		/**现象:当内部类被static修饰以后,new Outer3()报错*/
    		//6.用static修饰内部类以后,上面的创建语句报错,注释掉
    		//通过外部类的类名创建内部类对象
    		Outer3.Inner3 oi = new Outer3.Inner3();
    		oi.show();
    		
    		//7.匿名的内部类对象调用show()
    		new Outer3.Inner3().show();
    		
    		//9.访问静态内部类中的静态资源--链式加载
    		Outer3.Inner3.show2();
    	}
    }
    
    //1.创建外部类Outer3
    class Outer3{
    	//2.创建成员内部类Inner3
    	//5.内部类被static修饰—并不常用!浪费内存!
    	static class Inner3{
    		//3.定义成员内部类中普通的成员方法
    		public void show() {
    			System.out.println("我是Inner3类的show()");
    		}
    		//8.定义成员内部类的静态成员方法
    		static public void show2() {
    			System.out.println("我是Inner3的show2()");
    		}
    	}
    }
    

    静态资源访问时不需要创建对象,可以通过类名直接访问访问静态类中的静态资源可以通过”. . . ”链式加载的方式访问

    2.3局部内部类

    创建包:cn.tedu.Innerclass
    创建类:TestInnner4.java

    package cn.tedu.innerclass;
    /**本类用来测试局部内部类*/
    public class TestInner4 {
    	public static void main(String[] args) {
    		/**如何使用内部类的资源呢?
    		 * 注意:直接调用外部类的show()是无法触发内部类功能的
    		 * 需要再外部类中创建内部类对象并且进行调用,才能触发内部类的功能
    		 * */
    		//5.创建外部类对象调用show()
    		//7.当在外部类show()中创建局部内部类对象并且进行功能调用后,内部类的功能才能被调用
    		new Outer4().show();
    	}
    }
    //1.创建外部类Outer4
    class Outer4{
    	//2.创建外部类的成员方法
    	public void show() {
    		//3.创建局部内部类Inner4—不太常用!!!
    		/**位置:局部内部类的位置在方法里*/
    		class Inner4{
    			//4.创建局部内部类的普通属性与方法
    			String name;
    			int age;
    			public void eat() {
    				System.out.println("我是Inner4的eat()");
    			}
    		}
    		/**如何使用局部内部类的资源?*/
    		//6.在show()里创建内部类对象
    		Inner4 in = new Inner4();
    		in.eat();
    		System.out.println(in.name);
    		System.out.println(in.age);
    	}
    }
    

    2.4匿名内部类

    创建包:cn.tedu.innerclass
    创建类:TestInner5.java

    package cn.tedu.innerclass;
    /*本类用于测试匿名内部类
    * 匿名内部类没有名字,通常与匿名对象结合在一起使用*/
    public class TestInner5 {
        public static void main(String[] args) {
            //传统方式:创建接口的实现类+实现类实现接口中的抽象方法+创建实现类对象+通过对象调用方法
            //3.创建接口一对应的匿名对象与匿名内部类,并调用实现了的方法save()
            new Inter1(){
                @Override
                public void save() {
                    System.out.println("save()...");
                }
                @Override
                public void get() { }
            }.save();
    
            //5.创建抽象类对应的匿名对象与匿名内部类
            new Inter2(){
                @Override
                public void drink() {
                    System.out.println("一人饮酒醉");
                }
            }.drink();
            //7.调用普通类的功能怎么调用?创建匿名对象直接调用
            new Inter3().powerUp();
            new Inter3().powerUp();//new了2次,所以是两个匿名对象
            /*如果想要多次使用实现后的功能,还是要创建普通的对象
            * 匿名对象只能使用一次,一次只能调用一个功能
            * 匿名内部类其实就充当了实现类的角色,去实现未实现的抽象方法,只是没有名字而已*/
            Inter3 in = new Inter3();
            in.study();
            in.study();
            in.study();
            in.study();
            in.study();
            in.study();
    
        }
    }
    
    //1.创建接口
    interface Inter1{
        //2.定义接口中的抽象方法
        void save();
        void get();
    }
    //4.创建抽象类
    abstract class Inter2{
        public void play(){
            System.out.println("Inter2...play()");
        }
        abstract public void drink();
    }
    //6.创建普通类
    class Inter3{
        public void study(){
            System.out.println("什么都阻挡不了我想学习赚钱的决心");
        }
        public void powerUp(){
            System.out.println("我们会越来越强的!");
        }
    }
    

    总结:匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用

  • 相关阅读:
    [书目20130415]改变:28天让自己内心强大
    [引]软件著作权登记申请所需文件
    [转]动软代码生成器之模板功能介绍
    [转]C# 冒泡排序你还会吗?
    [转]细说ASP.NET Forms身份认证
    [转]listview加载性能优化ViewHolder
    [转]App for Android (2) —— Python篇
    [转]sqlserver 创建分区表
    [转]c# 四舍五入、上取整、下取整
    常用 Java 静态代码分析工具的分析与比较
  • 原文地址:https://www.cnblogs.com/elliottmoo/p/15686291.html
Copyright © 2020-2023  润新知