• Java 面向对象(六)


    抽象类和抽象方法

    抽象方法

    在方法前面添加了一个关键字 abstract

    抽象方法的特点

    (1)抽象方法是没有方法体的。

    (2)抽象方法必须得要定义在抽象类 或 接口当中 (在类前面添加上了一个abstract 就成为了抽象类)

    (3)抽象方法不能是私有的(private),不能使用 final 和 static 修饰。

    抽象类

    在类前面添加了一个关键字 abstract

    抽象类必须得要有子类才行。(抽象类一般都当作父类来继承)

    抽象类当中的注意点

    (1)抽象类是不能直接创建对象的。(不能通过new来实例化)

    (2)抽象类当中,可以有抽象方法 ,也可以有非抽象方法(普通方法:给子类调用的)

    (3)子类要去覆盖抽象方法方法,子类如果没有去覆盖抽象方法 ,也可以把子类也变成抽象类。让孙类去覆盖抽象方法。

    (4)构造方法不能定义为私有化(抽象方法必须得要让子类继承之后,才能实现内部的方法体。子类继承的话,先去调用父类的构造方法)

    (5)抽象类不能使用 final 来去修饰。

    抽象类与普通类的区别

    (1)普通类有的(方法,字段,构造器),抽象类都有。

    (2)普通类可以创建对象,抽象类不能创建对象。

    (3)抽象类可以包含抽象方法,也可以包含非抽象方法。

    (4)抽象类必须有子类才有意义。

    接口

    什么是接口

    硬件接口:指的是两个硬件设备之间的连接方式。硬件接口既包括物理上的接口(比如我们所以说的USB接口),还包括逻辑上的数据传送协议。

    在Java中,接口表示一种规范/约束,要求实现者必须遵循该规范,用来约束使用者应该怎么做。使用抽象方法来去定义一组功能,必须要实现者提供方法的实现。

    接口的好处

    接口只定义了类应当遵循的规范,却不关心这些类的内部数据和其功能的实现细节。站在程序角度上说接口只规定了类里必须提供的方法,从而分离了规范和实现,增强了系统的可拓展性和可维护性。

    接口的定义

    类的定义:

    class 类名{
        
    }
    

    接口的定义:

    interface 接口名称{
       
    }  
    

    接口也会生成对应的字节码

    接口是一个特殊的抽象类

    接口其实是一个特殊的抽象类,使用抽象方法来去定义一组功能,必须要实现者提供方法的实现。

    内部的 abstract 可以省略不写,如果没有在方法前面添加 abstract,会在编译时自动的添加上。

    void test();
    

    反编译后:

    public abstract void test();
    

    接口当中的注意点

    (1)接口是没有构造器,接口不能创建对象;抽象类是有构造器的,但是不能创建对象。

    (2)接口当中定义变量,都是全局的静态常量

    String name = "myxq";
    

    反编译后:

    public static final String name = "myxq";
    

    (3)接口当中 定义的方法 都是公共的抽象的方法

    void test();
    

    反编译后:

    public abstract void test();
    

    (4)接口当中可以定义内部类,内部类也是公共抽象(public static class)

    (5)接口是可以继承,它是可以多继承;类是不能多继承。

    接口的继承

    接口是可以继承,它是可多继承;类是不能多继承。

    interface  接口名称  extends  被继承的接口名, 被继承的接口名 {
    
    }
    

    接口继承的时候,不会去覆盖父接口的方法。接口的方法都没有方法体,覆盖父接口的方法没有意义。

    接口的实现

    类名  extends  其它的类(只能继承一个类)  implements  接口名(接口可以实现多个){
    
    }
    

    在实现类当中必须得要去覆盖接口当中定义的方法, 实现的方法必须得是 public 修饰。

    实现关系有时候也可以理解是继承关系。实现就可以看作子类覆盖父类(接口)的方法。覆盖的时候,子类的方法权限要比父类大,或者一样大,不能比它小,而接口的权限是 public,所以实现的方法必须得是 public 修饰。

    // 爬行动物规范
    interface Iwalkable {
    	void walk();
    	// public abstract void walk();
    }
    
    class Animal {
    	String name;
    	String Color;
    }
    
    class Cat extends Animal implements Iwalkable {
    
    	// 覆盖的时候,子类的方法权限要比父类大,或者一样大,不能比它小
    	public void walk() {
    		System.out.println("走猫步");
    	}
    
    }
    
    public class Test {
    	public static void main(String[] args) {
    		// 多态写法,把子类对象赋值给父类(接口)类型
    		Iwalkable cat = new Cat(); 	// 面向接口编程
    		// 多态运行时表现出来的还是子类的特征 (编译时,看左边,运行时,看右边)
    		cat.walk();
    	}
    }
    

    接口与抽象类的区别

    (1)相同点

    • 都是被其它类实现或者被继承
    • 都不能实例化
    • 都可以定义抽象方法 ,定义的抽象方法子类都必须得要覆盖。

    (2)不同点

    • 接口是没有构造器;抽象类当中是有构造器。
    • 抽象类可以包含普通方法和抽象方法;接口当中只能有抽象方法,不能有普通方法(带有方法体)
    • 接口当中默认成员变量,public static final 变量;-> 静态常量;抽象类当中是默认的权限
    • 接口当中默认方法,public abstract 方法名;抽象类当中是默认的权限

    面向接口编程

    什么是面向接口编程

    把实现类对象赋值给接口类型的变量

    面向接口编程的好处

    就是多态的好处:屏蔽了不同类之间实现差异,从而达到通用编程

    实例

    interface IUSB {
    	void swapData();
    }
    
    // 主板
    class MotherBoard {
    	void pluginIn(IUSB u) {
    		u.swapData();
    	}
    }
    
    // 键盘
    class KeyBoard implements IUSB {
    	public void swapData() {
    		System.out.println("打字");
    	}
    }
    
    // 鼠标
    class Mouse implements IUSB {
    	public void swapData() {
    		System.out.println("鼠标移动");
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		IUSB m = new Mouse();
    		IUSB k = new KeyBoard();
    
    		MotherBoard b = new MotherBoard();
    		b.pluginIn(m);
    		b.pluginIn(k);
    	}
    }
    

    内部类

    什么是内部类

    定义在类当中的一个类

    class Outter { // 外部类
    	String name = "myxq";
    
    	// 内部类
    	class Innner {
    		void test() {
    			System.out.println(name);
    		}
    	}
    }
    

    内部类可以直接访问外部类当中的成员(字段、方法、内部类)

    为什么要使用内部类

    (1)增强封装,把内部类隐藏在外部类当中,不允许其它类访问这个内部类

    (2)增加了代码一个维护性

    内部类的划分

    内部类可以分为四种

    (1)实例内部类:直接定义在类当中的一个类,在类前面没有任何一个修饰符

    (2)静态内部类:在内部类前面加上一个static

    (3)局部内部类:定义在方法的内部类

    (4)匿名内部类:属于局部内部的一种特殊情况

    提示:外部类的修饰符只能有两个, public 或者是 默认修饰;内部类可以使用很多个修饰符。

    实例内部类

    实例内部类:属于对象的内部类,不属于类的,不使用static修饰的内部类。它是直接定义在类当中的一个类,在类前面没有任何一个修饰符。

    class Outter {
    	String name = "myxq";
    
    	class Inner {
    		void test() {
    			System.out.println(name);
    		}
    	}
    }
    

    实例内部类的创建

    想要使用实例内部类,必须得要先创建外部类

    Outter out = new Outter();
    // 创建实例内部类
    // 创建内部类对象当中,会有一个外部类的引用
    Outter.Inner in = out.new Inner();
    

    创建内部类对象当中,会有一个外部类的引用

    反编译后:

    class Outter$Inner
    {
    
    	final Outter this$0;
    
    	void test()
    	{
    		System.out.println(name);
    	}
    
    	Outter$Inner()
    	{
    		this$0 = Outter.this;
    		super();
    	}
    }
    

    实例内部类注意点

    (1)想要使用内部类,必须得要先创建外部类

    Outter.Inner in = out.new Inner();
    

    (2)在内部类当中可以访问外部类当中的成员

    (3)在内部类当中,不能有静态的成员

    (4)外部类是不能直接访问内部当中的成员

    变量的访问

    就近原则

    class Outter {
    	String name = "Outername";
    
    	class Inner {
    		int age = 10;
    		String name = "inname";
    
    		void test() {
    			String name = "testname";
    			System.out.println(name);
    			System.out.println(this.name);
    			System.out.println(Outter.this.name);
    		}
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		Outter out = new Outter();
    		Outter.Inner in = out.new Inner();
    		in.test();
    	}
    }
    

    静态内部类

    静态内部类:在内部类前面加上static,属于类的内部类。

    class Outter {
    	static class Inner {
    		void test() {
    			System.out.println("test");
    		}
    	}
    }
    

    静态内部类的创建

    不需要创建外部类对象

    Outter.Inner in = new Outter.Inner();
    in.test();
    

    在静态内部类当中没有外部类的引用。因为它属于类,直接使用类调用即可

    反编译后:

    static class Outter$Inner
    {
    
    	void test()
    	{
    		System.out.println("test");
    	}
    
    	Outter$Inner()
    	{
    	}
    }
    

    静态内部类注意点

    (1)静态内部类是不需要创建外部对象

    Outter.Inner in = new Outter.Inner();
    in.test();
    

    (2)在静态内部类当中 ,是没有外部类引用

    (3)静态内部类,是可以访问外部类的静态成员,也可以访问外部类的普通变量。

    class Outter{
    	static String name = "myxq";
    	static class Inner{
    		void test() {
    			System.out.println(name);
    			System.out.println(Outter.name);
    		}
    	}
    }
    

    (4)访问静态内部类当中的静态成员

    class Outter {
    	static class Inner {
    		static String color = "black";
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		System.out.println(Outter.Inner.color);
    	}
    }
    

    (5)静态内部当中可以定义静态成员,也可以定义非静态成员

    静态内部类当中访问外部类的普通变量

    class Outter {
    	static String name = "myxq";
    	int age = 10;
    
    	static class Inner {
    		void test() {
    			System.out.println(name);
    			System.out.println(new Outter().age);
    		}
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		// 创建静态内部类
    		Outter.Inner in = new Outter.Inner();
    		in.test();
    	}
    }
    

    局部内部类

    局部内部类:定义在方法当中的内部类。

    class Outter {
    	void myxq() {
    		String name = "myxq";
    		class Inner {
    			void test() {
    				System.out.println(name);
    			}
    		}
    		Inner in = new Inner();
    		in.test();
    	}
    }
    

    局部内部类注意点

    (1)不能使用一些修饰 public private ...

    (2)局部内部只能在定义的方法当中使用

    (3)局部内部类当中是不能包含静态变量

    (4)局部内部类当中可以包含局部变量,使用的局部变量的本质是final(常量)

    class Outter {
    	void myxq() {
    		String name = "myxq";
    		class Inner {
    			int age = 10;
    			void test() {
    				System.out.println(name);
    				System.out.println(age);
    			}
    		}
    		Inner in = new Inner();
    		in.test();
    	}
    }
    

    反编译后:

    class Outter$1Inner
    {
    
    	int age;
    	final Outter this$0;
    	private final String val$name;
    
    	void test()
    	{
    		System.out.println(val$name);
    		System.out.println(age);
    	}
    
    	Outter$1Inner()
    	{
    		this$0 = final_outter;
    		val$name = String.this;
    		super();
    		age = 10;
    	}
    }
    

    匿名内部类

    匿名内部类:就是一个没有名字的局部内部类

    只使用一次的时候,使用匿名内部类。匿名内部类必须要有父类或者是有要实现的接口。

    匿名内部类是没有构造器。

    格式:

    new 父类的构造器 或  接口() {
    	内部写的代码(在new时候就会自动执行)
    }
    

    实例:

    没有使用匿名内部类前:一个类对应一个文件。

    interface IUSB {
    	void swapData();
    }
    
    class MotherBoard {
    	void pluginIn(IUSB u) {
    		u.swapData();
    	}
    }
    
    class Printer implements IUSB {
    	public void swapData() {
    		System.out.println("打印工作");
    	}
    }
    
    class KeyBoard implements IUSB {
    	public void swapData() {
    		System.out.println("打字");
    	}
    }
    
    class Mouse implements IUSB {
    	public void swapData() {
    		System.out.println("鼠标移动");
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		IUSB m = new Mouse();
    		IUSB k = new KeyBoard();
    		Printer p = new Printer();
    		MotherBoard b = new MotherBoard();
    		b.pluginIn(m);
    		b.pluginIn(k);
    		b.pluginIn(p);
    	}
    }
    

    使用匿名内部类后:

    interface IUSB {
    	void swapData();
    }
    
    class MotherBoard {
    	void pluginIn(IUSB u) {
    		u.swapData();
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {
    		MotherBoard b = new MotherBoard();
    
    		b.pluginIn(new IUSB() {
    			public void swapData() {
    				System.out.println("鼠标移动");
    			}
    		});
    
    		b.pluginIn(new IUSB() {
    			public void swapData() {
    				System.out.println("打字");
    			}
    		});
    
    		b.pluginIn(new IUSB() {
    			public void swapData() {
    				System.out.println("打印工作");
    			}
    		});
    	}
    }
    
  • 相关阅读:
    Oracle--SQL Developer创建连接及使用
    MongoDB--使用修改器修改文档
    MongoDB 的创建、查询、更新、删除
    window下 Mongodb无法访问28107的有关问题(转)
    十一、存储过程
    十、视图
    九、增、改、查数据
    七、联结表
    八、组合查询和全文本搜索
    六、聚合函数、数据分组
  • 原文地址:https://www.cnblogs.com/xzh0717/p/11212655.html
Copyright © 2020-2023  润新知