Java面向对象_接口、内部类

面向对象

接口

引用数据类型 : 类 , 数组 , 接口

接口中 是抽象方法的集合,只定义功能,不实现功能,用于让实现类去实现功能

接口是一种引用数据类型,可以看做是一种特殊的抽象类,完全抽象,一个类只能继承一个父类,但是可以实现多个接口

  • 接口和接口之间 是多继承 用逗号隔开 extends xx,xxx,xxxxx
  • 类和接口之间是多实现,用逗号隔开 implements xxx,xxx,xxx,xxx

声明方式 由 class 变成了 interface

语法 :

[修饰符] interface 接口名 {
}

1.7 只能有抽象方法
1.8 开始 可以有静态 可以有default (可以理解为成员方法,实现类可以调用可以覆写)
静态方法,使用接口名调用就行
default方法需要使用实现类对象调用 public default 返回值 方法名(参数) { 方法体 }
1.9 开始 支持 private 方法

但是 接口中 不支持成员变量,一般是static和final 并且 public static final 可以省略

  • 接口中 抽象方法 不需要加abstract 也不需要加public 因为默认就是

  • 接口没有构造方法,不能被实例化对象

  • 一个抽象类实现接口,可以实现 0~N个抽象方法

  • 一个非抽象类实现接口,需要实现所有的抽象方法

  • abstract 和 interface 的区别?

abstract是抽象的意思,是个修饰符,修饰的是抽象类,不能被实例化
interface是定义接口关键字,接口和接口之间是多继承,类和接口之间是多实现

实例 :

public class Interface_01 {

	public static void main(String[] args) {
		System.out.println(A.i);
		A.m1();
		E e = new E();
		e.m3();
//		2
//		-=---
//		-----

	}

}

interface A {
	// 都是静态常量
	public static final String SUCCESS = "SUCCESS";
	int i = 2;
	byte MAX_VALUE = 127;

	public static void m1() {
		System.out.println("-=---");
	}

	public default void m3() {
		System.out.println("-----");
	}

	public abstract void m2();
}

interface B {
	void m4();
}

//多继承
interface C extends A, B {
	void m5();
}

//抽象类实现 0~N 个抽象方法
abstract class D implements A, B {

}

class E implements C {

	@Override
	public void m2() {
		// TODO Auto-generated method stub

	}

	@Override
	public void m4() {
		// TODO Auto-generated method stub

	}

	@Override
	public void m5() {
		// TODO Auto-generated method stub

	}

}

类关系

1 继承 使用extends表示

类A extends 类B
接口A extends 接口B,接口C
类和类是单继承,接口和接口是多继承

2 实现 implements

类A implements 接口B,接口C
类和接口是多实现

3 依赖

某个类的方法中的局部变量,是另外一个类对象的引用
这种关系是临时性的,方法执行结束,关系就不存在了

4 关联

某个类的成员/静态变量是另一个类对象的引用
这个关系一般是长期性的

5 聚合

  • 整体和局部可以分离,各自具有生命周期
    比如 : 一个公司由员工构成,这时 就算公司倒闭,员工也依然存活
    员工也有员工的生命周期
  • 把好多有意义的模块,聚合到一起使用,形成一个有意义的功能,就算这个功能结束,也不会影响每个小模块的生命周期

比如A保存B的引用,这个引用一般是 调用处传递过来的,这样 调用处和A 都保存B 这个时候就算A销毁了,B也不会销毁,因为还有其他引用的指向

6 组合

  • 组合关系要强于聚合,也有的叫强聚合

同样是整体和局部,只不过不可分离,局部没有生命周期 比如 :
人,有眼睛,有腿,有胳膊…,如果人死了,胳膊也就动不了了,眼睛也就看不见了,都没有什么意义了

  • 他们的生命周期 是一起的

比如A保存B的引用,这个引用一般是自己创建的,(A的构造方法中或者成员变量直接初始化另一个类对象)
这样每创建一个A对象,都会去创建一个B对象,A对象销毁,B对象也会销毁,成为垃圾数据

实例 :

public class Test {
	// 关联关系 : 成员变量是另一个类对象引用
	A a = new A();

	public static void main(String[] args) {
		// 依赖关系 : 局部变量是另一个类对象引用
		B b = new B();
	}
}

//继承关系 类单继承
class A extends B {

}

class B {

}

//继承 接口多继承
interface C extends D, E {

}

interface D {

}

interface E {

}

内部类

  • 内部类 : 就是在类体中编写的类

内部类重要的作用 : 可以访问外部类私有化数据

变量 :

  1. 成员变量 — 普通内部类/成员内部类
  2. 静态变量 — 静态内部类
  3. 局部变量 — 局部内部类
  4. 形参和实参变量 — 匿名内部类

1 成员内部类

关于成员内部类

  1. 成员内部类可以看做成员变量
  2. 成员内部类中不能有静态声明
  3. 成员内部类中可以直接访问外部类所有的数据
  • 类体中没有static修饰的类是成员内部类

// 成员内部类中 不能有静态声明
// 成员内部类 可以使用 权限控制修饰符 , 比如 private class xxxx
// 编译之后的类名 外部类类名 内 部 类 类 名 0 1 O u t e r C l a s s 内部类类名 _01_OuterClass 01OuterClassInnerClass

实例 :

public class OuterClass_01 {
	private static String s1 = "静态变量";
	private String s2 = "成员变量";

	// 类体中没有 static 修饰的类是成员内部类
	class InnerClass {
		// 成员内部类中不能有静态声明
		// 成员内部类中可以使用权限修饰符,比如 : private class xxx
		// 编译之后的类名 外部类类名$内部类类名 OuterClass_01$InnerClass

//		static String aa = " ";
//		public static void m1() {
//			不能有静态声明
//		}
		public void m2() {
			// 可以直接访问外部类的所有属性
			System.out.println(s1);
			System.out.println(s2);
		}

		class A {

		}
	}

	public static void main(String[] args) {
		// 外部类对象
		OuterClass_01 oc = new OuterClass_01();

		// 使用外部类对象.new 内部类() 来创建内部类对象
		InnerClass inner = oc.new InnerClass();
		inner.m2();

		System.out.println(inner);
		InnerClass inner1 = new OuterClass_01().new InnerClass();
//		静态变量
//		成员变量
//		_17_InnerClass.OuterClass_01$InnerClass@15db9742

	}

}

2 静态内部类

  • 静态内部类,可以看做静态变量

在类体中使用static修饰的类是静态内部类

静态内部类中可以声明成员属性也可以声明静态属性

但是静态内部类中不能直接访问外部类的成员属性(需要使用外部类对象调用外部类的成员属性)

实例 :

public class OuterClass_02 {
	private static String s1 = "静态变量";
	private String s2 = "成员变量";

	static class InnerClass {
		// 静态变量
		static int i = 1;
		// 成员变量
		int b = 2;

		// 静态方法
		public static void m1() {
			System.out.println(s1);
			// 不能直接调用外部类的成员属性
//			System.out.println(s2);
			// 需要使用外部类对象调用成员属性
			System.out.println(new OuterClass_02().s2);
		}

		// 成员方法
		public void m2() {
			System.out.println(s1);
			// 不能直接调用外部类的成员属性
//			System.out.println(s2);
			// 需要使用外部类对象调用成员属性
			System.out.println(new OuterClass_02().s2);
		}
	}

	public static void main(String[] args) {
		// 访问静态变量
		OuterClass_02.InnerClass.m1();
		InnerClass.m1();

		InnerClass inner = new OuterClass_02.InnerClass();
		InnerClass inner1 = new InnerClass();
		inner.m2();
		inner1.m2();
	}

}

3 局部内部类

局部内部类 等同于 局部变量

局部内部类中访问外部类的局部变量的时候,局部变量需要加final修饰(1.8之前),但是局部变量的值不能更改

  • 不管是成员方法还是静态方法,都不能使用static修饰内部类

如果外部方法是成员方法的话,在内部类中可以直接访问外部类的所有属性
如果外部方法是静态方法的话,在内部类中不能直接访问外部类的成员属性,需要创建对象访问

不管方法是静态还是成员,局部内部类都不可以有静态声明

类名 :

如果多个方法的内部类类名不一致,就是 外部类类名$1内部类类名
如果内部类类名一致 , 就是 外部类类名$1内部类类名 , 外部类名$2内部类类名 依次类推

  • 使用局部内部类 必须在方法内部调用
    实例 :
public class OuterClass_03 {
	private static String s1 = "成员变量";
	private String s2 = "成员变量";

	public void m1() {
		int i = 10;
		// 不能更改 i 的值,等于是 final 修饰
		// i = 2;
		class InnerClass {
			// 不能有静态声明
//			public static void m3() {}
			public void m4() {
				System.out.println(s1);
				System.out.println(s2);
				System.out.println(i);
			}
		}
		// 使用局部内部类,必须在方法内部调用
		InnerClass inner = new InnerClass();
		inner.m4();
		System.out.println(inner);
	}

	public static void m2() {
		int i = 10;
		// 不能更改 i 的值,等于是 final 修饰
		// i = 2 ;
		class InnerClass {
			// 不能有静态声明
//			public static void m3() {}
			public void m4() {
				System.out.println(s1);
				// 静态方法中的内部类,没有办法直接访问外部类的成员属性,需要用对象调用
//				System.out.println(s2);
				System.out.println(new OuterClass_03().s2);
				System.out.println(i);
			}
		}
		// 使用局部内部类,必须在方法内部调用
		InnerClass inner = new InnerClass();
		inner.m4();
		System.out.println(inner);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OuterClass_03 oc = new OuterClass_03();
		oc.m1();
		OuterClass_03.m2();
	}

}

4 匿名内部类

匿名内部类 : 指在调用方法的时候,需要传入一个接口的实现类对象,这个时候可以不传递实现类对象,传递一个匿名内部类

语法 : 方法(new 接口名(){ 类体 });

传入匿名内部类的时候,会自动创建一个对象传入,因为没有名字,我们不能自己创建

类名为 外部类类名$1 以此类推

不能有静态声明,但是可以声明常量(public static final int i = 10)

  • 静态变量 / 静态方法 都不行
    不能直接访问外部类的成员属性,需要使用对象调用
    实例 :
public class OuterClass_04 {
	private static String s1 = "静态变量";
	private String s2 = "成员变量";

	public static void main(String[] args) {
//		IUserService userService = new UserService();
//		m1(userService);

		m1(1, new IUserService() {
			public static final int i = 2;

			public void m1() {

			}

			@Override
			public void login() {
				System.out.println("啥也不是");
				System.out.println(this);
				System.out.println(s1);
				// 需要使用对象调用,不能直接调用外部类的成员属性
//				System.out.println(s2);
			}

		});
	}

	public static void m1(int i, IUserService userService) {
		userService.login();
	}
}

interface IUserService {
	public void login();
}

//class UserService  implements IUserService{
//	@Override
//	public void login() {
//		
//	}
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值