-
面向接口编程
工厂模式,命令模式
package com.study.day10.part1.dao;
// 工厂模式
public class DaoFactory {
public static UseDao getUserDao(){
return new UserDaoJdbcImpl();
}
}
public interface UseDao {
int selectUseCount();
}
public class UserDaoJdbcImpl implements UseDao{
@Override
public int selectUseCount() {
System.out.println("通过UserJdbcImpl查询用户数量");
return 100;
}
}
package com.study.day10.part1.util;
// 命令模式
public class ArrayUtil {
// 冒泡排序;
// 此处可以调用接口引用对象,也可以调用类引用对象;
public static void sort(int[] arr,ComparatorImpl comparator){ 、
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length -1 - i; j++) {
// 比较两数
if(comparator.compare(arr[j], arr[j + 1]) > 0){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
public interface Comparator {
int compare(int m, int n);
}
public class ComparatorImpl implements Comparator {
@Override
public int compare(int m, int n) {
if(m > n){
return 1;
}else if(m == n){
return 0;
}else
return -1;
}
}
public class InterfaceUse implements Constant{
public static void main(String[] args) {
// 工厂模式示例:
/* 如果代码为:UseDao dao1 = new UserDaoJdbcImpl();
* UseDao dao2 = new UserDaoJdbcImpl();
* 假定不再使用Jdbc用户数据访问方式,就得把所有带有Jdbc的访问语句删除
* 那就直接使用工厂模式,将用户数据的访问方式封装起来,直接调用工厂;
*/
UseDao dao = DaoFactory.getUserDao();
System.out.println(dao.selectUseCount());
int[] nums = {4, 7, 8, 4, 2, 1};
// 命令模式示例:
ArrayUtil.sort(nums, new ComparatorImpl());
System.out.println(Arrays.toString(nums));
}
}
-
接口和抽象类
-
相同点
1.他们都不能实例化,都可以被其他类实现和继承;
2.他们都可以包含抽象方法、普通实现类、普通的子类都必须实现这些抽象方法;
-
不同点:接口是一种规范,抽象类体现的是一种模版模式的设计;
1.接口不能包含构造方法,抽象类可以包含构造方法(给继承子类使用);
2.接口不包含初始化块,而抽象类可以包含初始化块;
3.接口只能定义静态常量,抽象类可以定义普通成员变量;
4.接口的方法:默认,静态,抽象;抽象类:普通,抽象;
5.一个类只能有一个父类,但是可以实现多个接口;
-
-
内部类
定义在其他类内部的类,而包含内部类的类叫外部类;
-
内部类的作用
1.内部类提供了一种新的封装方式,可以将内部类隐藏在外部类中;
2.便于访问外部类中的成员,如成员内部类可以直接访问外部类的私有成员;
3.对于仅用一次的类,采用内部类(匿名内部类)实现会更加方便;
-
分类
-
成员内部类
1.定义在外部类内部,与其他成员评级,它是一种新的成员;
2.可以被任意的访问修饰符修饰,和成员一样;
3.被static修饰的静态内部类,否则叫非静态内部类;
-
局部内部类
方法内定义的类(基本不用)
-
匿名内部类
通常定义在方法调用之时,它没有类名,适合创建只需要使用一次的类;
-
非静态内部类
1.非静态内部类中不可以定义任何静态成员;
2.非静态内部类可以访问外部类的实例变量;
3.外部类的静态初始化块、静态方法不能访问非静态内部类;
4.同名的变量可以用“this.”“外部类.this.”进行区分;
5.在外部类的外部,也可以实例化非静态内部类,语法如下:
外部类.内部类 变量名 = 外部类.实例.new 内部类构造方法;
-
-
public class OuterClass {
private int width = 1024;
public void print(){
Inner inner = new Inner(1920, 1080);
inner.print();
System.out.println("Outer" + inner.height);
System.out.println("Outer" + inner.width);
}
static{
// Inner inner = new Inner(1920,1080);
}
public static void show(){
// Inner inner = new Inner(1920,1080);
}
// 非静态内部类
public class Inner{
private int width;
private int height;
public Inner(int width, int height){
this.height =height;
this.width =width;
}
public void print(){
System.out.println("inner:" + this.width);
System.out.println("inner:" + this.height);
System.out.println("outer" + OuterClass.this.width);
}
// public static int i;
// static{}
//public static void show(){} 都是不行的,非静态内部类中不能定义静态成员;
}
}
public class InnerClassUse {
public static void main(String[] args) {
OuterClass.Inner inner =
new OuterClass().new Inner(1920,1080);
inner.print();
}
}
- **静态内部类**
1.静态内部类可以包含静态成员,也可以包含非静态成员;
2.静态内部类不能访问外部类的实例成员,只能访问它的静态成员;
3.外部类的所有方法、初始化块都能访问其内部定义的静态内部类;
4.在外部类的外部,也可以实例化静态内部类:
外部类.内部名 变量名 = new外部类.内部类构造方法();
- **匿名内部类**
1.匿名内部类没有名称,适合创建只需要使用一次的类;
2.创建匿名内部类之时,会立刻得到这个类的一个实例;
3.匿名内部类在创建时,必须继承一个父类或者实现一个借口;
new 父类构造器(参数列表){
...}
new 待实现的接口(){
...}
以数组排序为例:
int[] nums = {4, 7, 8, 4, 2, 1};
ArrayUtil.sort(nums, new Comparator(){
@override
public int compare(int m, int n){
...}
});
-
枚举类
一组数据固定且有限;
可以定义静态常量来表示这些数据,也可以定义枚举类来表示这些数据。
-
常量
public static final int SPRING = 1;
缺点:类型不安全,可以当做帧数参与计算,并且输出的意义不明确;
-
枚举类
一种特殊的类,可以清晰地枚举出每一项数据,可以避免错误的运算;
-
枚举类的规范
1.enum关键字定义(不是class);
2.枚举类可以定义成员变量、成员方法、构造方法,也可以实现接口;
3.枚举类默认继承于java.lang.Enum类,并且不能继承与其他父类;
4.非抽象的枚举类默认使用final修饰,所以枚举类不能派生出子类;
5.枚举类的构造方法默认使用private修饰,并且只能使用private修饰;
6.枚举类的所有实例,必须在第一行显示出,他们默认是public static final的;
-
enum Gender{
MALE,FEMALE;
}
enum Gender{
MALE("男"),FEMALE("女");
private String name;
Gender(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
- 如何实现接口
enum Gender implements Printer{
MALE, FEMALE;
public void print(){
...}
}
enum Gender implements Printer{
MALE(){
public void print(){
...}
}
FEMALE(){
public void print(){
...}
}
}
-
抽象的枚举类
1.可以再枚举类中定义抽象方法,此时枚举类为抽象类,但不能用abstract修饰该类;
2.枚举类需要显示创建枚举值,所以每个枚举值都要实现抽象方法,否则会编译报错;
enum Gender implements Printer{
MALE(){
public void print(){
...}
}
FEMALE(){
public void print(){
...}
}
public abstract void print();
}
// 枚举类相当于提前构造好了有限个数的类的对象实例;这些实例必须写在枚举类中;
public enum Direction{
EAST(name:"东"), WEST(name:"西"), NORTH(name:"北"), SOUTH(name:"南");
private final String name;
Direction(String name){
this.name = name;
}
public String gerName(){
return this.name;
}
}
// System.out.println(Drection.North.getName()); 构造器的用法