16、static关键字、接口

16_static关键字、接口

1、static
1.1 static 修饰的静态代码块
1.1.1 代码块
{} 大括号里面的内容就是代码块

1、构造代码块
	定义在类内
2、局部代码块
	定义在方法内

构造代码块演示

public class Person {
	private int id;
	private String name;
	private int age;
	
	/*
	 * 这就是构造代码块
	 * 构造代码块 在成员变量之后 构造方法之前
	 * 
	 * 特征:
	 * 		1、构造代码块在调用执行构造方法时一定运行
	 * 		2、构造代码块在调用执行方法之时 首先执行
	 * 
	 * 构造代码块内容会在 Java 编译器编译过程中 直接给所有当前类的构造方法提供
	 * 并且在所有的构造方法的 第一行
	 * 
	 * 可以将构造方法相同的功能模块 使用构造代码块封装提供给所有构造方法 避免代码冗余
	 */
	{
		System.out.println("构造代码块");
	}
	
	public Person() {
		System.out.println("构造方法");
	}

	public Person(int id) {
		this.id = id;
		System.out.println("构造方法");
	}

	public Person(int id, String name) {
		this.id = id;
		this.name = name;
		System.out.println("构造方法");
	}

	public Person(int id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
		System.out.println("构造方法");
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

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

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

局部代码块演示

public class Demo2 {

	public static void main(String[] args) {
		int num = 10;
		
		// 局部代码块 优化变量内存占用时间 提升代码内存效率 降低内存占用 
		{
			int num2 = 20;
		}
		
		System.out.println(num);
		
		//报错 num2 为局部变量
		//System.out.println(num2);
	}

}

1.1.2 static 修饰静态代码块基本语法和代码案例
//静态代码块要求在 class 大括号内
static {}
class SinglePerson {
	
	int num = 10;
	
	static int test = 20;
	
	/*
	 * 静态代码块
	 * 	只在类文件加载时执行一次
	 * 
	 * 静态代码块只能当前类中使用 static 修饰的静态内容 不能使用非静态内容
	 */
	static {
		System.out.println("静态代码块");
		System.out.println(test);
		testStaticMethod();
		
//		System.out.println(num);
//		test();
	}
	
	public void test() {
		System.out.println("非静态成员方法");
	}
	
	public static void testStaticMethod() {
		System.out.println("静态成员方法");
	}
	
}

public class Demo3 {
	public static void main(String[] args) {
		System.out.println("测试");
		
		SinglePerson singlePerson1 = new SinglePerson();
		SinglePerson singlePerson2 = new SinglePerson();
	}
}
1.1.3 静态代码块特征
1、static 修饰的静态代码块 之在程序的加载阶段执行一次
2、static 修饰的静态代码块 不能使用类内的非静态成员(成员变量和成员方法)
3、static 修饰的静态代码块 可以直接使用类内的静态成员(类变量和类方法)
4、static 修饰的静态代码块 用于项目的启动过程中的初始化操作
	可以利用 static 代码加载阶段执行的特征 将一些项目所需的配置操作前置
	用于 读取配置文件 加载相关驱动 加载第三方资源
1.2 static 题目
public class Demo4 {
	static Demo4 d1 = new Demo4();

	static Demo4 d2 = new Demo4();
	
	static {
		System.out.println("静态代码块");
	}
	
	{
		System.out.println("构造代码块");
	}
	
	public Demo4() {
		System.out.println("构造方法");
	}
	
	public static void main(String[] args) {
		Demo4 d = new Demo4();
	}
}
代码执行流程
1、从 main 方法进入程序 查找静态内容按顺序加载执行
 2、加载时执行静态成员变量 d1 赋值语句
		实例化 new一个构造方法 执行构造代码块和构造方法 依次执行打印语句
3、加载时执行静态成员变量 d2 赋值语句
 		实例化 new一个构造方法 执行构造代码块和构造方法 依次执行打印语句
4、加载时执行静态代码块
 		打印输出
5、执行 main 方法 
		new一个构造方法 执行构造代码块和构造方法 依次执行打印语句

代码执行结果
static题目

2、interface 接口
2.1 Java 中定义接口的格式

基本语法、格式规范和使用要求

关键字:
	interface
格式:
interface 接口名 {
	成员变量
	成员方法
}

1、接口是一个特殊的类型 也是一个数据类型
2、接口名要求符合命名规则 见名知意 大驼峰命名法
3、接口类型变量 是一个引用数据类型变量
//接口的定义和实现

/*
 * 接口定义格式:
 * 
 * interface 接口名 {
 * 		成员变量;
 * 		成员方法;
 * }
 * 
 */
/*
 * 自定义接口
 */
interface A {
	/**
	 * 成员变量
	 * 
	 * 接口中的成员变量的【缺省属性/默认属性】 public static final
	 * 		public 表示数据公开 任何位置都可以使用
	 * 		static 静态修饰 
	 * 		final 最终修饰/不可更改修饰
	 * 
	 * 【带有名称的常量】下划线命名法 所有字母全大写 不同单词之间用 _ 连接
	 */
	int NUM = 1;
	
	/**
	 * 成员方法
	 * 
	 * 接口中的成员方法【缺省属性/默认属性】public abstract
	 * 		public 表述方法公开
	 * 		abstract 修饰 方法为抽象方法 没有方法体
	 * 
	 */
	void test();
	
	/*
	 * 接口具体做什么 不是由本身决定 而是由继承接口的类决定
	 */
}
2.2 遵从接口
类遵从接口
关键字:
	implement
格式:
class 类名 implements 接口名 {}
/**
 * @author Echo
 *
 * 类遵从接口
 * 格式:
 * class 类名 implements 接口名 {
 * 		
 * }
 * 
 * 一个非 abstract 修饰类【遵从】接口 要求实现接口中的所有缺省属性为
 * public abstract 修饰的方法
 */
class TypeA implements A{
	@Override
	public void test() {
		System.out.println("TypeA 类遵从接口 A 实现 接口 A 中的 test 方法");
	}
}

public class Demo1 {
	public static void main(String[] args) {
		//匿名对象直接调用方法
		new TypeA().test();
		
		//实例化对象之后 通过对象名调用方法
		TypeA typeA = new TypeA();
		typeA.test();
	}
}

2.3 接口的特殊用法
2.3.1 类可以遵从多个接口
//一个类可以实现多个接口

interface B {
	void testB();
	
	void test();
}

interface C {
	void testC();
	
	void test();
}
/*
 * TypeB 类同时遵从两个接口 分别是 interface B 和 interface C
 * 不同的接口直接使用 , + 空格 隔开
 * 
 * 语法要求:
 * 		1、遵从多个接口的类 要求分别实现每个接口中的方法
 * 		2、如果多个接口中存在完全相同的方法声明 类中只实现一个方法即可
 */
class TypeB implements B, C {
	
	@Override
	public void testB() {
		System.out.println("TypeB 遵从接口 B 实现 testB 方法");
	}
	
	@Override
	public void testC() {
		System.out.println("TypeB 遵从接口 C 实现 testC 方法");
	} 
	
	public void test() {
		System.out.println("TypeB 遵从接口 B 和接口 C 实现两个接口中方法声明一样的方法【同规则方法】");
	};
}

public class Demo2 {
	public static void main(String[] args) {
		TypeB typeB = new TypeB();
		
		typeB.test();
		typeB.testB();
		typeB.testC();
	}
}

2.3.2 类可以继承父类同时遵从接口
//子类可以在继承父类的同时实现接口

class SuperClass {
	public void test() {
		System.out.println("父类成员方法");
	}
}

interface D {
	void testD();
}

/**
 * 
 * @author Echo
 * 
 * 一个类可以在继承类的同时遵从接口
 */
class TypeC extends SuperClass implements D {
	//【实现】接口 D 中的方法
	@Override
	public void testD() {
		System.out.println("TypeC 遵从接口 D 实现 testD 方法");
	}
	
	//【重写】父类中的方法
	@Override
	public void test() {
		System.out.println("TypeC 重写父类 SuperClass 的 test 方法");
	}
} 

public class Demo3 {
	public static void main(String[] args) {
		TypeC typeC = new TypeC();
		
		typeC.testD();
		typeC.test();
	}
}

2.3.3 接口可以继承其他接口 并且可以多继承
//接口可以继承其他接口 并且可以多继承

interface USB1_0 {
	void usb1_0Connect();
}

interface USB2_0 {
	void usb2_0Connect();
}

/**
 * 
 * @author Echo
 *
 *	接口可以继承其他接口 并且可以多继承
 */
interface USB3_0 extends USB1_0, USB2_0 {
	void usb3_0Connect();
}

/**
 * 
 * @author Echo
 *
 *	类遵从接口 要求实现接口中的所有的缺省属性/默认属性为 public abstract 修饰的方法
 *	包括当前接口的父类接口中的缺省属性/默认属性的方法
 */
class TypeD implements USB3_0 {
	
	//实现 USB3_0 接口中的 usb1_0Connect 方法
	@Override
	public void usb1_0Connect() {
		System.out.println("usb1_0Connect");
	}
	
	//实现 USB3_0 接口中的 usb1_0Connect 方法
	@Override
	public void usb2_0Connect() {
		System.out.println("usb2_0Connect");
	}
	
	//实现 USB3_0 接口中的 usb1_0Connect 方法
	@Override
	public void usb3_0Connect() {
		System.out.println("usb3_0Connect");
	}
}

public class Demo4 {
	public static void main(String[] args) {
		TypeD typeD = new TypeD();
		
		typeD.usb1_0Connect();
		typeD.usb2_0Connect();
		typeD.usb3_0Connect();
	}
}

2.3.4 JDK 1.8 版本以上特征

允许在接口中使用 default 关键字修饰方法 修饰的方法为默认方法 允许有方法体

//接口中的默认成员方法

interface E {
	void test();
	
	/*
	 * default 关键字修饰的方法
	 * 可以被重写 也可以直接用
	 */
	default void testDefaultMethod() {
		System.out.println("JDK 1.8以上版本允许的默认方法 default 修饰");
	}
	
	//接口中 static 修饰的成员方法可以通过 接口名调用
	static void testE() {
		System.out.println("静态成员方法");
	}
}

class TypeE implements E {
	@Override
	public void test() {
		System.out.println("TypeE 类遵从接口 E 只需要完成接口 E 中的缺省属性为 public abstract 的 test 方法");
	}
	
	
	//重写接口中 default 修饰的 默认成员方法
	@Override
	public void testDefaultMethod() {
		System.out.println("TypeE 类遵从接口 E 重写接口中由 default 修饰的默认 testDefaultMethod 成员方法");
	}
	
}

public class Demo5 {
	public static void main(String[] args) {
		TypeE typeE = new TypeE();
		
		typeE.test();
		typeE.testDefaultMethod();
		
		//interface E 中的静态成员方法 通过接口名调用
		E.testE();
		
	}
}

2.3.5 接口语法问题
1、接口中是否可以定义 static 修饰的静态成员方法?
	可以
	static 修饰的成员方法可以直接通过该接口名调用。
	
2、一个方法是否可以同时使用 abstract 和 static 两个关键字修饰?
	不行
	abstract 关键字修饰的方法没有方法体
	static 关键字修饰的方法是在类文件加载阶段已经准备就绪 必须明确所有和执行相关的内容
	即 static 修饰的方法必须有方法体 abstract 修饰的方法必须没有方法体 两者无法合作
3、多态
3.1 父类引用指向子类对象
class Animal {}

class Monkey extends Animal {}
class Tiger extends Animal {}
class Lion extends Animal {}

public class Demo1 {
	public static void main(String[] args) {
		Animal animal = new Animal();
		
		//多态 父类引用指向子类对象
		Animal monkey = new Monkey();
		Animal tiger = new Tiger();
		Animal lion = new Lion();
		
//		Monkey monkey = new Monkey();
//		Tiger tiger = new Tiger();
//		Lion lion = new Lion();
		
		/*
		 * 【Java语法规范】
		 * 		一个方法的所需参数类型为父类类型 
		 * 		传入的对象类型除了该父类类型对象外还可以传入子类类型对象
		 */
		feedAnimal(animal);
		feedAnimal(monkey);
		feedAnimal(tiger);
		feedAnimal(lion);
	}
	
	/**
	 * 喂食方法 所需参数是动物类对象
	 * 
	 * @param animal Animal 动物类对象
	 */
	public static void feedAnimal(Animal animal) {
		/*
		 * getClass() 可以获取当前对象对应完整 包名.类名
		 */
		System.out.println(animal.getClass() + "来吃饭了~");
	}
}

3.2 接口的引用指向遵从接口的实现类对象
/*
 * 【语法规则】
 * 一个方法的所需参数为接口类型 
 * 方法实际参数要求是 实现接口的类的对象 或者是实现接口类的子类
 */

interface USB {
	/**
	 * 要求所有的 USB 设备必须完成的方法 用于描述/实现当前设备的功能
	 */
	void connect();
}

/**
 * 鼠标类 遵从 USB 接口 可以认为是一个 USB 设备
 * @author Echo
 */
class Mouse implements USB {
	@Override
	public void connect() {
		System.out.println("USB 设备——鼠标 控制光标操作");
	}
}

/**
 * G502 继承 Mouse 类 间接遵从 USB 接口
 * G502 也是一个 USB 设备
 * @author Echo
 *
 */
class G502 extends Mouse {
	@Override
	public void connect() {
		System.out.println("200RMB 鼠标 一个是G502 一个是其它");
	}
}

/**
 * 键盘类 遵从 USB 接口 可以认为是一个 USB 设备
 * @author Echo
 */
class Keyboard implements USB {
	@Override
	public void connect() {
		System.out.println("USB 设备——键盘 输入设备");
	}
}

/**
 * IKBC 继承 Keyboard 类 可以认为是一个 USB 设备
 * @author Echo
 *
 */
class IKBC extends Keyboard {
	@Override
	public void connect() {
		System.out.println("IKBC:200-300RMB 性价比极高");
	}
}

class PC {
	/*
	 * 电脑预留 USB 接口 用于连接 USB 设备
	 * 认为电脑通过 USB 接口连接 USB 设备
	 * 认为是一个方法
	 */
	/**
	 * PC 电脑类 USB 接口连接方法 方法所需参数是 USB 接口类型 所需要的实际参数是 USB 设备
	 * @param usb
	 */
	public void usbInterfaceConnect(USB usb) {
		/*
		 * 实际执行对象是 USB 设备
		 */
		usb.connect();
	}
}

public class Demo2 {
	public static void main(String[] args) {
		//实例化 PC 电脑类对象
		PC pc = new PC();
		
		//实例化鼠标和键盘 都是 USB 接口
//		Mouse mouse = new Mouse();
//		Keyboard keyboard = new Keyboard();
		
		//多态 接口的引用指向遵从接口的实现类对象
		USB mouse = new Mouse();
		USB keyboard = new Keyboard();
		
		//PC 电脑类 传递的参数为接口实现类的对象
		pc.usbInterfaceConnect(mouse);
		pc.usbInterfaceConnect(keyboard);
		
		//G502 是 Mouse 类的子类 也可以作为当前方法的实现类
//		G502 g502 = new G502();
		
		//多态 接口的引用指向遵从接口的实现类对象
		USB g502 = new G502();
		
		//传递的参数是接口实现类 Mouse 类的子类对象
		pc.usbInterfaceConnect(g502);
		
		//IKBC 是 Keyboard 类的子类
//		IKBC ikbc = new IKBC();
		
		//多态 接口的引用指向遵从接口的实现类对象
		USB ikbc = new IKBC();
		
		//传递的参数是接口实现类 Keyboard 类的子类对象
		pc.usbInterfaceConnect(ikbc);
	}
}

3.3 引用数据类型之间的强制类型转换
class SuperClass {
	public String str = "父类成员变量";
	
	public void testA() {
		System.out.println("父类成员方法testA");
	}
	
	public void testB() {
		System.out.println("父类成员方法testB");
	}
}

/**
 * SubClass 是 SuperClass 的子类
 * @author Echo
 *
 */
class SubClass extends SuperClass {
	public int num = 10;
	
	@Override
	public void testB() {
		System.out.println("重写父类中的 testB 方法");
	};
	
	public void testC() {
		System.out.println("子类方法");
	}
}

public class Demo3 {
	public static void main(String[] args) {
		//父类的引用数据类型变量指向一个子类对象【多态】
		SuperClass subClass = new SubClass();
		
		/*
		 * 虽然父类的引用存储的数据类型是一个子类 但是对外的类型是父类类型 
		 * 无法直接使用子类的变量和非重写父类的方法 不能赋值给子类类型的另一个对象
		 */
		
		//subClass.num = 20; 报错
		//subClass.testC(); 报错
		//SubClass sub = subClass; 报错
		
		/*
		 * 多态对象可以调用
		 * 		1、父类中的变量
		 * 		2、当子类中没有重写父类的方法 调用的是父类中的方法
		 * 		2、子类重写父类中的方法 调用的是子类重写的方法
		 */
		System.out.println(subClass.str);
		subClass.testA();
		subClass.testB();
		
		/*
		 * 使用强制类型转换 把父类引用对外的数据类型转为子类类型
		 * 【强制类型转换】可行 安全 无丢失
		 */
		
		SubClass sub = (SubClass)subClass;
		System.out.println(sub.num);
		sub.testC();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值