Java 面向对象编程之接口内部类

接口,内部类,抽象类本质上也是类,是抽象的抽象类,这三种类有各自的特点。

1. 抽象类、 设计与实现的分开

  1. 抽象类:定义了抽象方法的类,不能实例化,只能被子类实现 , 用关键字abstract修饰。
  2. 抽象方法:只定义了方法体,没有定义内容。
  3. 作用:为所有子类建立一个模板。
    抽象类具有具有以下的语法规则需要遵循:
      1、一个类中如果有抽象方法,则这个类必须是抽象类。
      2、抽象类中可以没有抽象方法。
      3、抽象类是不能存在实例对象的,换句话说就是抽象类就是为了被继承而存在的。
      4、一个子类如果继承了抽象类,必须实现抽象类中定义的所有抽象方法。
      5、抽象类可以继承抽象类,可以不重写父类的方法。
abstract class Person{
    public abstract void study()    ;   //抽象方法
    public void eat(){
        System.out.println("吃的技能");
    }
}

简单地说:万物可归类,类本身是对于客观世界的抽象,在描述客观世界的过程中 ,需要抽象出高度抽象的类,用来描述同类事物的共性,可以用abstract来修饰,抽象类有抽象方法,也有常规方法,方法是对于事物行为的描述,抽象方法对于同类事物的相同行为的描述,比如说,抽象类动物有抽象方法吃饭和睡觉,具体类猫也有吃饭和睡觉的行为,猫类实现抽象类动物类,继承抽象方法吃饭和睡觉,这样猫也就有了吃饭和睡觉的方法,通过重写类实现猫的吃饭和睡觉的具体行为。
2.接口 规范和具体实现的分离

  1. 定义: 只包含有抽象方法和常量,通过 interface修饰,接口可以实现多继承。
    常量用public static final 修饰,只有方法标识符,没有方法体。
  2. 作用:用来描述类有哪些行为,对内的一组行为的描述,接口不能实例化。
    接口是规范,定义了一组规则,在现实世界中,如果你是,,,,那么你应该,,,,
    本质是契约,开发项目往往是面向接口编程。
  3. 定义一个接口
    在这里插入图片描述
    4.实现接口
    在这里插入图片描述
  • 接口和抽象类的比较
    在这里插入图片描述

1.语法层面上的区别

1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

2.设计层面上的区别
  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
3. 内部类

public class OuterClass {
    private String name ;
    private int age;

    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;
    }
    
    class InnerClass{
        public InnerClass(){
            name = "chenssy";
            age = 23;
        }
    }
}

- 内部类定义
内部类是定义在一个类中的类。 如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动) ,显然,此处不能单方面用属性或者方法表示一个心脏,而需要一个类,而心脏又在人体当中,正如同是内部类在外部内当中
每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,内部类的存在使得Java的多继承机制变得更加完善。
java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题 没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。
- 内部类 类型
在Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。
- [ ] 成员内部类
成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所有 成员属性和方法, 包括private的,但是外围类要访问内部类的成员属性和方法则需要通过内部类实例来访问。
在成员内部类中要注意两点,第一:成员内部类中不能存在任何static的变量和方法;第二:成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类,如下例中,构建内部类的实例,要求必须外部类的实例先存在 ,外部类的外部/外部类的静态方法:new Outer().new Inner();
外部类的实例方法: new Inner(); this.new Inner();

  • 内部类和外部类的访问关系
    当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
    外部类.this.成员变量
    外部类.this.成员方法
    成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
class MemberOuter{
	private String s1 = "Outer InstanceMar";
	private String s2 = "OuterStatic s2";
	public void setS1(String s1) {
		this.s1 = s1;
		new MemberOuter().new MemberInner();
		this.new MemberInner();  //此时MemberOuter已经实例化完成,所以可以使用this
		new MemberInner().test2();
	}
	public static void  test2 (){
		new MemberOuter().new MemberInner();
		/*this.new MemberInner();  
		 * 此时MemberOuter没有实例化完成,所以不可以使用this
		 * static 是在MemberOuter构造器前使用,所以此时this不能使用
		 * 
*/
}
  	class MemberInner{
		 String s1= "Inner  instanceMae  ";
		static final String s4 = "static final  MemberInner";
			
				void test2(){
					System.out.println(" s1 =" + s1);
					System.out.println(" Outter MemberOuter.this.s1 =" + MemberOuter.this.s1);
					System.out.println("s2 = "+s2);
				}
		}
}
 public class MemberInnerTest {
	public static void main (String args []){
	/*	MemberOuter.MemberInner mm =  new MemberOuter().new MemberInner();
		mm.test2();*/
		MemberOuter mo = new MemberOuter();
		mo.setS1("");		
	}
}

运行结果:
在这里插入图片描述

  • 局部内部类
    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
    局部内部类可以访问的外部类的成员根据所在方法体不同, 如果在静态方法中,可以访问外部类中所有静态成员,包含私有。如果在实例方法中,可以访问外部类中所有的成员,包含私有。局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。
public class LocalInnerTest {
 private int a = 1;
 private static int b = 2;
 public void test() {
 	final int c = 3;
 	class LocalInner {
 		public void add1() {
 			System.out.println("a= " + a);
 			System.out.println("b= " + b);
 			System.out.println("c= " + c);
 		}
 	}
 	new LocalInner().add1();
 }
 static public void test2() {
 	final int d = 5;
 	class LocalInner2 {
 		public void add1() {
 			// System.out.println("a= " + a);
 			System.out.println("b= " + b);
 			System.out.println("c= " + d);
 		}
 	}
 	new LocalInner2().add1();
 }
 public static void main(String args[]) {
 	// LocalInnerTest() lc = new LocalInnerTest();
 	new LocalInnerTest().test2();
 	new LocalInnerTest().test();
 }
}

运行结果如下:
在这里插入图片描述
- [ ] 匿名内部类
假如只创建了一个类的对象,而没有命名,这样的类就是内部类 ,没有构造器。一般隐式的继承某一个父类或者实现某一个接口,没有class,interfaceimplements,extends关键字。

 interface Pen {
	public void write();
}
class  Pencil implements Pen {
	@Override
	public void write() {
		//铅笔 的工厂
	}
} 
class Person {
	public void user(Pen pen) {
		pen.write();
	}
}
 
public class tEST1 {
	public static void main(String args[]) {
		Person guo = new Person();
		
		guo.user(new Pen() {
			@Override
			public void write() {
				System.out.println("写字");
			}
		});
	}
 
}

运行结果:
在这里插入图片描述
匿名内部类适用的比较多,要么定义一个接口,然后直接new一个接口并完善该类的方法,要么直接调用import已经写好的类,如在设计Java swing中的字体时:enterbutton.setFont(new Font("华文行楷",Font.BOLD,35)); 这样相当于直接new Font()来设计字体。
参考 Java提高篇(十)详解匿名内部类

  • 静态内部类
    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的。和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用
class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
} 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
 }

运行结果 12

Java接口 抽象类和内部类是常用的类的变形,也就是说,他们是类,是对于类的抽象,以便更好的实现对于客观世界的描述。
引用:
https://www.cnblogs.com/dolphin0520/p/3811437.html

猜你喜欢

转载自blog.csdn.net/weixin_41792162/article/details/84317758