第十次课总结及思考

第十次课,主要讲了接口、内部类、枚举类、垃圾回收机制(GC)等知识。

一、接口

      1、特点:

        (1)使用interface关键字修饰;

        (2)支持多继承,如:

package interface_10th;

public class InterfaceExtends {
	
	interface interfaceA{
		int property_A = 5;
		void testA();
	}
	interface interfaceB{
		int property_B = 6;
		void testB();
	}
	//interfaceC获得了父类的常量
	interface interfaceC extends interfaceA,interfaceB{
		int property_C = 7;
		void testC();
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		System.out.println(interfaceC.property_A);
		System.out.println(interfaceC.property_B);
		System.out.println(interfaceC.property_C);
	}

}
运行结果:

5
6
7

        2、命名:首字母为“I”。

        3、 接口中,成员变量:默认public final static修饰;

                             所有方法都是抽象方法,使用public abstract修饰
               注意点:成员变量和方法的修饰符只能用public,缺省状态下默认的也是public,不是default


        4、与抽象类的区别:
                     a.接口全都是抽象方法;
                     b.抽象类可以部分是抽象方法。

        5、用途:

                 a. 接口中可以定义变量,以方便以后调用;

                 b. 在创建实现接口的类的对象时,可以使用InterfaceName objectName = new ImplementClassName()(推荐使用)

                 c. 实现接口方法时,必须使用public访问控制修饰符,如:

package interface_10th;

public interface Shape {
	
//	修饰符只能用public,注意默认的是public
	 abstract double calPerimeter();
	public abstract String getType();
	
	
	public static final String s = "123";

}


package interface_10th;


public class Exercise implements Shape{

	
	double pi = 3.14;
	double r;

	public Exercise(double r) {
		
		this.r = r;
	}
	
	@Override
	public double calPerimeter() {
		
		return 2*pi*r;
	}

	@Override
	public String getType() {
		
		return "圆形";
	}
	public double getArea() {
		return pi*r*r;
	}
	
	public static void main(String[] args) {
		
		Exercise exercise = new Exercise(10);
		System.out.println(exercise.calPerimeter());
		System.out.println(exercise.getArea());
		
//		或者可以以下面这种方式创建对象。因为接口和规范是分类的,所以推荐使用下面这种方式
		Shape shape = new Exercise(1);
		String s =  Shape.s;
		System.out.println("接口里面的变量s = " + s);
		System.out.println(shape.calPerimeter());

	}

}
运行结果:

62.800000000000004
314.0
接口里面的变量s = 123
6.28

二、内部类

       1、内部类可以使用外部类的成员变量(包括私有)而不用生成外部类的对象

       2、如下面的代码所示:

public class StaticInnerClass {
	private int age = 10;
	class InnerClass{
		private int age = 11;
		void printInfo(){
			//局部变量
			int age = 12;
			System.out.println(age);
			//内部类变量
			System.out.println(this.age);
			//外部类变量
			System.out.println(StaticInnerClass.this.age);
		}
	}
	
	public static void main(String[] args) {
		
		StaticInnerClass.InnerClass ic = new StaticInnerClass().new InnerClass();
		ic.printInfo();
	}
	

运行结果:

12
11
10
            利用this.age可以得到内部类变量,利用StaticInnerClass.this.age可以获取外部类变量。
          3、 静态内部类:只能调用外部静态变量

          4、方法内的内部类:

public class StaticInnerClass{<pre name="code" class="java">
private int age = 10;public static void main(String[] args) {StaticInnerClass oc = new StaticInnerClass();oc.sayHello();}// 方法内声明内部类,只能在方法内部使用public void sayHello() {//方法里面的类class Test{public void printInfo(){//可以直接访问外部类成员变量System.out.println("访问外部类成员变量age = "+age);}}new Test().printInfo();}}

 运行结果: 

访问外部类成员变量age = 10


              5、 匿名内部类

                 (1)一次性使用,用来简化代码
                 (2)前提条件:实现一个接口、父类或抽象类,如:

package innerclass_10th;

public class NoNameClass {

	public static void main(String[] args) {
		
		//做法传统
		People children = new Children();
		System.out.println("传统代码写法:");
		children.eat();
		System.out.println();
		
		
		//抽象类——匿名内部类实现
		
		//当chilren只使用一次
		//匿名内部类
		System.out.println("匿名内部类实现抽象类:");
		People boy = new People() {
			
			@Override
			void eat() {
				
				System.out.println("人在吃东西");
			}
		};
		boy.eat();
		System.out.println();
		
		
		
		//接口——匿名内部类实现
		System.out.println("匿名内部类实现接口:");
		Animal animal = new Animal() {
			
			@Override
			public void walk() {

				System.out.println("animal is walking!");
			}
		};
		animal.walk();
		System.out.println();
		
		
		//需要用final修饰
				final int age = 100;
				//多线程
				new Thread(new Runnable() {
					
					@Override
					public void run() {
						System.out.println("多线程里面使用内部类:");
						System.out.println("局部变量:"+age);
						System.out.println("随机数:"+Math.random());
					}
				}).start();
	}

}

abstract class People{
	abstract void eat();
	
}

class Children extends People{
	@Override
	void eat() {
		// TODO Auto-generated method stub
		System.out.println("eat");
		
	}
}
//接口
interface Animal{
	//抽象方法
	public abstract void walk();
}
三、枚举类

        1、enum的全称为enumeration,是JDK 1.5中引入的的新特性

        2、使用enum定义的枚举类默认继承自java.lang.Enum,非Object

        3、使用enum定义的枚举类不能派生子类,即其他类不能继承枚举类

        4、枚举类所有实例必须放在第一行显示列出,系统自动添加public static final修饰,如果在代码中打出这三个单词会报错

        5、枚举类的构造器的访问权限控制符只能用private,缺省情况下默认也是使用private,放在所列出的实例所在的行之后
        6、EnumClass.values返回该枚举类的所有实例,是一个数组

        7、枚举类不能进行实例化,即无法通过new EnumClassName()进行实例化操作

        8、几个常用的方法:

           (1)name():返回枚举实例的名称

           (2)ordinal():返回枚举值在枚举类中的索引,从0开始

           (3)toString():类似name()

           (4)valueOf(enumType,name):返回指定枚举类中的指定名称(name)的枚举值

        具体看下面的例子:

package enum_10th;

public enum SeasonEnum {

	//列出四个枚举实例-->对象、实例
	SPRING,SUMMER,FALL,WINNER;
	private SeasonEnum(){
		
	}
}



package enum_10th;

import java.util.Scanner;

public abstract class EnumTest {

	public static void main(String[] args) {

		
		
		//用values返回该枚举类的所有对象
		for (SeasonEnum seasonEnum : SeasonEnum.values()) {
			//打印每一个对象,所有以下3行结果一样
//			System.out.print(seasonEnum + " ");
//			System.out.print(seasonEnum.toString() + " ");
			System.out.print(seasonEnum.name() + " ");
			
			
		}
		
		
		//
		//底层已经帮我们做好了,不用new
		SeasonEnum se = SeasonEnum.SPRING;
		//索引从0
		System.out.println(se.ordinal());
		
		//控制台输入一个字符串,验证是否等于某个枚举类实例
		System.out.print("请输入季节:");
		Scanner in = new Scanner(System.in);
		String season = in.next();
		
		SeasonEnum seTest = Enum.valueOf(SeasonEnum.class, season);
		
		System.out.println("输入的季节:" + seTest.toString());
	}

}
运行结果:

SPRING SUMMER FALL WINNER 0
请输入季节:SPRING
输入的季节:SPRING

当控制台输入的字符串在枚举类中不存在,会抛出一下异常:

SPRING SUMMER FALL WINNER 0
请输入季节:1
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant enum_10th.SeasonEnum.1
	at java.lang.Enum.valueOf(Enum.java:236)
	at enum_10th.EnumTest.main(EnumTest.java:38)

四、垃圾回收机制(GC)

      1、什么时候垃圾回收:花括号结束或对象的引用为null

      2、GC不会回收物理资源(例如数据库连接、网络IO等资源),只回收堆内存的对象
      3、GC无法精确控制垃圾回收的运行,合适的时候GC
      4、在回收任何对象之前,都会调用finalize(),看看能否让它”重生“
      5、对象在jvm堆区的状态:可达状态、可恢复状态、不可达状态
         
(1)可达状态:存在引用变量引用这个对象。
         
(2)可恢复状态:不存在引用变量引用这个对象,此时处于可恢复状态,系统正准备回收它,在此之前会先调用finalize()方法,看看里面有没有让它“重生”的机会,如果没有就会被回收。

          (3)不可达状态:对象与所有引用变量的关联被切断,永久性失去了引用,系统才会真正回收该对象所占用的资源。
       6、强制垃圾回收:静态方法:System.gc();实例方法:Runtime.getRuntime().gc();(推荐)

五、作业:

       场景:一个系统的数据库是可以随时切换的,目前支持连接MySql和SqlServer,甚至以后还有可能连接Oracle数据库
       要求:利用抽象模板的思想和接口规范的思想实现以上场景
       提示:数据库操作过程包含连接(connect),查询(query),释放(dispose),具体细节不用实现,体现思路即可。

package homework;

public interface IDao {

	//连接数据库
	public abstract void connect(String dbName);
	
	//查询
	public abstract void query(String dbName);
	
	//释放
	public abstract void dispose(String dbName);
}

package homework;

public abstract class DBImpt implements IDao{

	@Override
	public void connect(String dbName) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void query(String dbName) {
		// TODO Auto-generated method stub
		System.out.println(dbName+"正在查询...");
	}
	@Override
	public void dispose(String dbName) {
		// TODO Auto-generated method stub
		
	}
	
}

package homework;

public class MySQLimpt extends DBImpt {

	private String DBName;
	public MySQLimpt(String dBName) {
		this.DBName = dBName;
		System.out.println("数据库名:" + this.DBName);
		connect(DBName);
		query(DBName);
		dispose(DBName);
	}
	@Override
	public void connect(String dbName) {
//		super.connect();
		System.out.println(dbName+"已连接!");
	}
	@Override
	public void query(String dbName) {
		super.query(dbName);
	}
	@Override
	public void dispose(String dbName) {
//		super.dispose(dbName);
		System.out.println(dbName+"已释放!");
	}
}

package homework;

public class OracleImpt extends DBImpt {

	private String DBName;
	public OracleImpt(String dBName) {
		this.DBName = dBName;
		System.out.println("数据库名:" + this.DBName);
		connect(DBName);
		query(DBName);
		dispose(DBName);
	}
	@Override
	public void connect(String dbName) {
//		super.connect(dbName);
		System.out.println(dbName+"已连接!");
	}
	@Override
	public void query(String dbName) {
		super.query(dbName);
	}
	@Override
	public void dispose(String dbName) {
//		super.dispose(dbName);
		System.out.println(dbName+"已释放!");
	}
}

package homework;

public class SQLServer extends DBImpt {

	private String DBName;
	public SQLServer(String dBName) {
		this.DBName = dBName;
		System.out.println("数据库名:" + this.DBName);
		connect(DBName);
		query(DBName);
		dispose(DBName);
	}
	
	@Override
	public void connect(String dbName) {
//		super.connect(dbName);
		System.out.println(dbName+"已连接!");
	}
	@Override
	public void query(String dbName) {
		super.query(dbName);
	}
	@Override
	public void dispose(String dbName) {
//		super.dispose(dbName);
		System.out.println(dbName+"已释放!");
	}
}

package homework;

import java.util.Scanner;

public class DaoFactory {

	public static void main(String[] args) {

		DBImpt dbImpt = null;
		System.out.print("请选择数据库(1为MySQL,2为SQLServer,3为Oracle):");
		Scanner scanner = new Scanner(System.in);
		String input = scanner.next();
		switch (input) {
		case "1":
			
			dbImpt = chooseDBImpt("MySQL");
			break;
		case "2":
			
			dbImpt = chooseDBImpt("SQLServer");
			break;
		case "3":
			
			dbImpt = chooseDBImpt("Oracle");
			break;

		default:
			break;
		}
	}
	
	public static DBImpt chooseDBImpt(String DBName) {

		DBImpt dbImpt = null;
		switch (DBName) {
		case "MySQL":
			
			dbImpt = new MySQLimpt(DBName);
			if (dbImpt != null) {
				
				return dbImpt;
			}
		case "SQLServer":
			
			dbImpt = new SQLServer(DBName);
			if (dbImpt != null) {
				
				return dbImpt;
			}
		case "Oracle":
			
			dbImpt = new OracleImpt(DBName);
			if (dbImpt != null) {
				
				return dbImpt;
			}

		default:
			break;
			
		}
		return null;
	}

}
运行结果:

请选择数据库(1为MySQL,2为SQLServer,3为Oracle):2
数据库名:SQLServer
SQLServer已连接!
SQLServer正在查询...
SQLServer已释放!

六、推荐两篇博文,感兴趣的读者可以参考一下:

       1、java 内存区域和GC机制
       2、java常量池概念

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值