接口
可以理解为特殊的抽象类
关键字interface -->接口
接口的优点
- 接口是功能体的集合
- 是一个引用数据类型
- 能够解耦
- 规定开发规范
jdk在1.7之前
属性:
必须是公共的静态的常量 public static final
public staic final 可以选择性省略(默认)
方法:必须是公共的抽象的方法
public abstract 返回值类型 方法名();
public absract 可以选择性省略
注意:
-
接口的实现与类的继承非常像,但是不一样在:
- 子类继承父类就可以直接使用父类的内容
- 实现类实现接口,也拥有接口中的能力,但是需要实现类自己去实现这个功能
- 接口实现的关键字是implement,继承的关键字是extends
-
类只能单继承,接口可以多实现,一个类需要继承父类后实现接口.
- 如果先接口后继承,会造成系统无法判断接口的个数.
-
接口也不能实例化
-
接口的使用只能通过类去实现接口
-
具体的实现类:重写了所有的抽象方法+按需新增
-
抽象类的实现:按需重写了抽象方法+按需新增,具体的子类才能使用
- 在抽象类中,可以全部实现,也可以部分实现
//抽象实现类 abstract class Demo02 implements InterfaceDemo02{ // @Override // public void demo2() { // // TODO Auto-generated method stub // // } }
-
-
继承和实现的几种情况
- 接口和接口之间是可以继承的
- 类和接口之间只能实现
- 接口之间可以多继承
- 类和接口之间可以多实现
//定义一个接口InterfaceDemo02
interface InterfaceDemo02{
public void demo1();
}
//定义一个接口InterfaceDemo03
interface InterfaceDemo03{
public void demo2();
}
//定义一个接口InterfaceDemo04 并继承InterfaceDemo02及InterfaceDemo03
interface InterfaceDemo04 extends InterfaceDemo02,InterfaceDemo03{
}
实现了接口
public class Demo implements InterfaceDemo02, InterfaceDemo03 {//与只实现InterfaceDemo04作用相同
@Override
public void demo2() {
System.out.println("实现了接口02");
}
@Override
public void demo1() {
System.err.println("实现了接口03");
}
}
jdk1.8中新增的内容
在接口中可以定义方法体的方法
- 默认方法:default关键字修饰(必须是显式的)
- 使用:通过实现类使用
- 静态方法
- 使用:接口名使用
public interface InterfaceDemo05 {
//默认方法
public default void moren(){
System.out.println("我是默认方法");
}
//静态方法
public static void test(){
System.out.println("我是静态方法");
}
}
//实现类
class Impl implements InterfaceDemo05{
}
测试
public class Test {
public static void main(String[] args) {
//默认方法通过类实现
Impl i=new Impl();
i.moren();
//静态方法通过接口名.方法调用
InterfaceDemo05.test();
}
}
设计模型
单例模式
保证一个类只能有一个对象,这个特点形式的类成为单例模式,但是不影响类中原有功能.
实现
- 构造器私有化
- 私有的 静态的该类引用,存储创建唯一的对象
- 公共的 静态方法方式
两种方式
饿汉式
当第一次调用的时候才创建这个实例 —线程不安全,效率较高
示例
//饿汉式
public class SingTon {
//1.构造器私有化
private SingTon(){
}
//2.私有的,静态的该类的引用,存储创建唯一的对象
//在类的第一次加载时候,创建一个唯一的实例
private static SingTon single=new SingTon();
//3.公共的 静态的方法方式
//返回值:当前数据类型 参数:没有
public static SingTon newInstance(){
//将当前创建的实例返回出去
return single;
}
}
懒汉式
在类的第一次加载完成之后,就创建这个实例 —线程安全,效率较低
示例
//懒汉式
public class Single {
//1.私有的构造函数
private Single(){
}
//2.私有的 静态的 该类的引用,存储创建唯一的对象
//先创建一个对象的默认参数为null
private static Single single=null;
//3.公共的静态的该类的引用
public static Single newInstance(){
//先判断实例是不是为空,如果为空则新建
//如果不为空则返回上一次对象的地址
if(single==null){
Single single=new Single();
}
return single;
}
}
代理模式
静态代理:
- 真实角色和代理角色实现相同的接口|继承相同的父类
- 代理角色持有真实角色的引用:成员属性进行维护
- 代理行为
注意:减少与真实角色的交流,降低耦合度,起到功能的扩展,方便后期维护
/*经理要通过人事招人,相当于 技术部经理 找了 人事当代理
真实角色:经理
代理:人事
行为:招人(人事和经理都需要实现)
代理模式就是把真实角色作为代理角色的一个成员变量
*/
public class StaticProxy {
public static void main(String[] args) {
}
}
//经理
class Manager implements Hiring{
@Override
public void hiring() {
System.out.println("我是经理,我要招人");
}
}
//人事
class Hr implements Hiring{
Manager manager;
//完全可以通过构造函数把真实角色引入到这个代理角色中
public Hr(Manager manager) {
super();
this.manager = manager;
}
@Override
public void hiring() {
System.out.println("我是人事,我要初试");
//重头戏 把真实角色当成代理模式的一个成员
this.manager.hiring();
System.out.println("成功录取");
}
}
//行为:招人
interface Hiring{
void hiring();
}
//测试
class Test{
public static void main(String[] args) {
Manager m=new Manager();
Hr h=new Hr(m);
h.hiring();
}
}
工厂模式
/*
*需求:我们直接从工厂拿车,如果是两轮输出两轮
* 四轮输出四轮
*
*/
public class Factory {
public static void main(String[] args) {
Car two=new TwoCar();
Car four=new FourCar();
Factory f=new Factory();
two.make();
f.factory(two);
two.run();
four.make();
f.factory(four);
four.run();
}
/*
有一家工厂可以造两个轮子也可以造四个轮子
一工厂是可以生产车的,这个是一个功能(方法)
结果:确定这个是方法
二工厂是可以生产不同的车的,可以创建不同的对象
结果:确定方法体的内容
三工厂无论生产哪种类型的车都是车,所以返回值一定是车
结果:确定返回值类型
四工厂生产车,需要给输入值
结果:确定参数
*/
//看传入的是否是 TwoCar或ForCar的一个实例
public static Car factory(Car srt){
if(srt instanceof TwoCar){
System.out.println("在造两轮");
}
if(srt instanceof FourCar){
System.out.println("在造四轮");
}
return srt;
}
}
interface Car{
void make();
void run();
}
class TwoCar implements Car{
@Override
public void make() {
System.out.println("我是造两轮的模板");
}
@Override
public void run() {
System.out.println("乌龟");
}
}
class FourCar implements Car{
@Override
public void make() {
System.out.println("我是造四轮的模板");
}
@Override
public void run() {
System.out.println("飞一样的感觉");
}
}
内部类
- 成员内部类
- 静态内部类
- 私有内部类
- 局部内部类
- 匿名内部类
成员内部类
当内部类作为外部类的成员,就是成员内部类
外部成员----------内部类
特点:
- 是成员就具有成员的特点,就是可以使用成员修饰符修饰
- 是类就有类的特点,可以继承及实现
- 内部类可以使用外部类的内容,包括私有的
- 在外部类中可以通过内部类的对象使用其成员
- 成员内部类中不能定义静态内容除了静态常量
package inner05;
//这个是Outer类
public class Outer01 {
//外部类的成员元素
int haha=1;
//在这个Outer类,有一个成员是类,该类名字为Inner,就是成员内部类
//只要是类就可以继承和实现
class Inner extends A implements B{
//成员内部类 的成员元素
String name="小王";
static final int age=35;
int haha=5;
//在这个Inner类中,有一个方法
public void inner(){
int haha=10;
System.out.println("我是成员内部类的成员方法");
//可以使用使用内部类的成员变量
System.out.println(name);
//如何获取外部类的成员内容 外部类名.this.属性|方法();
System.out.println("外部haha的值"+Outer01.this.haha);
//如果获取内部类的成员内容,this.属性|方法();
System.out.println("内部haha的值"+this.haha);
//如果获取局部变量,直接写
System.out.println("局部haha的值"+haha);
}
}
//以上是内部类的空间
/*如何使用内部类
* 在外部类中的方法中,创建一个内部类对象
* 调用内部的对象进行使用.
*
* 主方法:先创建一个外部类,通过外部类中的方法
* 外部类中的方法调用了内部对象,在使用
* 内部对象的方法
*/
public void outer(){
//创建一个内部类对象
System.out.println("我是外部类的方法");
Inner in=new Inner();
in.inner();
}
public static void main(String[] args) {
//在主方法中新建当前外部类的对象
Outer01 o1=new Outer01();
o1.outer();
}
}
class A{}
interface B{}
私有内部类
- 私有内部类可以使用外部类中的私有内容
- 外部类中可以使用私有内部类中的私有内容,需要通过内部类对象使用
- 私有的内部类中只能在外部类中使用,其他类中无法使用
public class Outer02 {
private int a=5;
//私有内部
private class Inner{
private int b=10;
private void inner(){
System.out.println("我是私有内部类的方法");
//私有内部类可以使用 外部类私有的内容
System.out.println(a);
// outer();
}
}
//外部类中的方法
void outer(){
System.out.println("我是外部类的方法");
/*外部类如何使用私有内部类的私有内容
* 必须通过内部类的对象
*/
Inner in=new Inner();
in.inner();
}
}
静态内部类
- 只有静态内部类中可以定义静态的内容,除了静态的内容
- 静态内部类中使用外部类中的成员,通过外部类对象使用,因为内部类是静态
- 在其他类中无法直接使用,只能是在外部类中方法中调用了内部类对象才能是使用
public class Outer03 {
private static String haha="外部类中的静态变量";
private String hehe="外部类中的成员变量";
//静态内部类
static class Inner{
static int a=5;
int b=51;
//静态内部类的静态方法
//总原则:静态的可以直接用,成员的需要通过对象使用
static void inner(){
//静态直接用
System.out.println(a);
//内部类的成员的,通过内部对象
System.out.println(new Inner().b);
//成员直接用
System.out.println(haha);
//外部类的成员,通过外部对象
System.out.println(new Outer03().hehe);
}
}
//外部类的方法
public void outer(){
//在外部类中中,可以直接通过外部对象
//直接使用静态内部,因为它是静态的
System.out.println(Inner.a);
System.out.println(new Inner().b);
}
}
局部内部类
- 方法中的内部类
- 不能使用成员修饰符 public static(final可以)
- 局部只能在它当前定义的方法中使用,通过对象使用
- 如果想要在局部内部类中使用当前方法的参数,这个参数必须被final修饰,在jdk1.8中final可以省略,但是默认
public class Outer04 {
static String name="小";
/*局部内部类
* 就是在方法内部定义类
*
*/
//外部类的方法
public static void test(final int args){
// args=100;
int a=5;
//定义一个方法中的类
class Inner{
int b=5;
public void inner(){
//局部变量可以直接使用
System.out.println(b);
//方法中的成员变量也可以直接使用
System.out.println(a);
//想要在局部类中使用,外部类的内容,其内容必须被static修饰
System.out.println(name);
//想要使用方法的参数,该参数必须别final修饰,在jdk1.7之前必须显式调用
System.out.println(args);
}
}
//只能通过当前定义的方法中使用
Inner in=new Inner();
in.inner();
}
//外部类方法
public void outer04(){
/* //无法通过内部类对象使用内部类
Inner in=new Inner();*/
}
}
匿名内部类
有一些实现类,没有自己本身的作用,就是为了重写抽象方法,浪费类名,项目中可能造成类过多情况,所以就有了匿名内部类
public class AnonymousDemo {
public static void main(String[] args) {
//匿名类方式一 接口多态
//为什么可以采用这个方式呢?
//Smoke接口可以接收来自实现该接口的类
//new-->创建 Smoke()-->实现了Smoke该接口 {}-->方法体中实现的内容
Smoke s=new Smoke(){
@Override
public void smoke() {
System.out.println("匿名方式一:实现接口中的方法");
}
@Override
public void haha() {
System.out.println("匿名方式一:实现接口中的方法");
}
};
//匿名类方式一的使用
s.smoke();
s.haha();
//匿名方式二:没有应用接收内部类的对象地址,造成只能在当前行使用
new Smoke(){
@Override
public void smoke() {
System.out.println("匿名方式二:实现接口中的方法");
}
@Override
public void haha() {
System.out.println("匿名方式二:实现接口中的方法");
}
}.haha();
//匿名方式三:把整个匿名类当成方法的实际参数
test(new Smoke(){
@Override
public void smoke() {
System.out.println("匿名方式三:实现接口中的方法");
}
@Override
public void haha() {
System.out.println("匿名方式三:实现接口中的方法");
}
});
}
//匿名方式三:先定义一test方法
static void test(Smoke s){
s.smoke();
}
}
interface Smoke{
void smoke();
void haha();
}
//一般我们要使用接口都需要通过创建一个类
//但是这个类,我们只是用来实现,并没有其他的功能
//太过浪费类名了,我们可以使用匿名类来实现
class Demo implements Smoke{
@Override
public void smoke() {
System.out.println("实现接口中的方法");
}
@Override
public void haha() {
System.out.println("实现接口中的方法");
}
}