Java日志三「抽象类和接口」

**

抽象类和接口

**
抽象类是一个泛泛的类。举个例子,现在有一个图形,并不告诉你是什么类型的图,然后让你求这个图形的面积。由于给的范围太不具体太抽象,导致我们没办法来求出这个图形的面积。这个图形就可以成为一个抽象的类。一个图形抽象类定义如下:

public abstract class Graphic {
	public abstract void caculateAera(double l,double w);//计算面积肯定需要两个参数
	//一个抽象方法,只有函数头,因为具体怎么实现不确定
}

在class前加上abstract关键字,一个抽象类定义就完成啦。上面的抽象类有一个抽象方法来计算面积,但是没有方法体,这是因为我们并不知道如何计算面积。一个抽象方法只能在抽象类中定义,但是具体的方法也可以在抽象类中定义。(比如计算周长,我们不需要知道是什么图形,只需要知道所有边的长度也可以计算周长)

一个抽象类不可以创建对象

public static void main(String[] args) {
	//Graphic g=new Graphic();错误写法,抽象类不可以创建对象,必须用一个子类来继承抽象父类
	}

现在我们被告知,该图形是一个三角形和矩形,我们现在就可以通过继承一个抽象类的方式来具体化Graphic这个抽象类。
Triangle类:

public class Triangle extends Graphic {
	@Override
	public void caculateAera(double l,double w) //必须覆盖重写父类中所有的抽象方法,不然报错
	{
		System.out.println(l*w/2);
	}

Rectangle类:

public class Rectangle extends Graphic {
	@Override
	public void caculateAera(double l,double w) //必须覆盖重写父类中所有的抽象方法,不然报错
	{
		System.out.println(l*w);
	}
}

以上是通过继承来实现对抽象类的具体化,一个抽象类的子类还可以是一个抽象类,但是一个具体的类(非抽象)的子类就不可以是一个抽象类了。

接口

现在我们看一个和抽象类非常像的东西叫接口。

接口是引用数据类型,是多个类的公共规范。从Java9开始,一个接口可以包含:
1.常量
2.抽象方法
3.默认方法(Java8以后的版本包含)
4.静态方法(Java8以后的版本包含)
5.私有方法(Java9以后的版本包含)

同时接口不可以有构造方法和静态代码块。

下面是我定义的一个接口MyInterfaceAbstract,我把上面接口可以包含的常量和四大方法都写进去,一些需要注意的地方写在了注释里:

public interface MyInterfaceAbstract {

	public static final int NUM=10;//前三个关键字可以不写,但是就算不写,系统也是默认这三个,不可以改变。若定义的时候不赋值默认为0,一样不可改变。
	//常量的名称要全大写
	public abstract void method1();
	public void method2();
	abstract void method3();
	void method4();
	//以上四个都是抽象方法,两个关键字都可以省略
	
	public default void methodDefault() 
	{
		System.out.println("这是一个默认方法AAA");
		methodPrivate();
	}
	//默认方法可被接口实现类对象直接调用,也可以在实现类中覆盖重写 
	
	public static void methodStatic() 
	{
		System.out.println("这是一个静态方法");
		methodPrivate2();
	}
	//静态方法不可以被接口的实现类对象直接调用,直接通过接口名称来调用
	
	/*
	 问题描述:默认方法与静态方法有许多重复的代码,产生了重复代码问题
	 
	 解决:
	 1.普通私有方法:解决默认方法的重复代码问题
	 2.静态私有方法:解决静态方法的重复代码问题
		
	 私有方法不可以被实现类使用
	 */
	
	 private void methodPrivate() 
	 {
		 System.out.println("这是默认方法里面的重复代码");
	 }
	 
	 private static void methodPrivate2() 
	 {
		 System.out.println("这是静态方法里面的重复代码");
	 }
}

上面说了接口和抽象类非常像,我们同样也需要一个与具体类相似的东西来具体化接口,我们把这样的类称作实现类。
但是为了引出实现类的某些注意事项,我们在定义一个简单的接口MyInterfaceAbstractB

public interface MyInterfaceAbstractB {

	public abstract void method1();
	
	public default void methodDefault() 
	{
		System.out.println("这是一个默认方法BBB");
	}
}

这个接口里面非常简单,只有一个抽象方法method1与默认方法methodDefault。实现类与一般的子类不同的是前者可以实现多个接口,下面是一个实现类

public class MyInterfaceAbstractImpl implements
MyInterfaceAbstract,MyInterfaceAbstractB{
//一个实现类可以implement多个接口,这一点一父类子类不同
	
	@Override
	public void method1() 
	{
		System.out.println("这是第一个抽象方法");
	}// MyInterfaceAbstract与MyInterfaceAbstractB中都有method1,但只需要覆盖重写一次
	
	@Override
	public void method2() 
	{
		System.out.println("这是第二个抽象方法");
	}
	
	@Override
	public void method3() 
	{
		System.out.println("这是第三个抽象方法");
	}
	
	@Override
	public void method4() 
	{
		System.out.println("这是第四个抽象方法");
	}
	
	@Override
	public void methodDefault() 
	{
		System.out.println("这是重写的默认方法");
	}//MyInterfaceAbstract与MyInterfaceAbstractB中都有一个相同名称的默认方法,但是方法提不一样,这样就必须对该默认方法重写

}

实现类同样也需要覆盖重写所实现接口的所有抽象方法,但是像method1这样在两个接口都有的抽象方法(函数头一样)就只需要覆盖重写一次。

像methodDefault这样在MyInterfaceAbstract中和MyInterfaceAbstractB中都给出了定义,函数头一样但是方法体不同,这就产生了默认方法冲突。对于冲突的默认方法,我们也必须在实现类中进行覆盖重写。

同时一个实现类也可以有一个父类,而且父类方法优先(这里主要介绍接口没有让上面的实现类有一个父类)。

下面我们在main函数里创建一个MyInterfaceAbstractImpl对象调用一下四种类型的方法和常量

public static void main(String[] args) {
	MyInterfaceAbstractImpl impl=new MyInterfaceAbstractImpl();//创建一个实现类的对象,不能创建接口的对象
    impl.method1();
	impl.method2();
	impl.method3();
	impl.method4();
	//调用覆盖的抽象方法
		
	impl.methodDefault();//调用默认方法
	MyInterfaceAbstract.methodStatic();//调用静态方法
	System.out.println(MyInterfaceAbstract.NUM);//使用接口中的常量
	}

结果

这是第二个抽象方法
这是第三个抽象方法
这是第四个抽象方法
这是重写的默认方法
这是一个静态方法
这是静态方法里面的重复代码
10

还有一点接口的小知识,当一个接口继承(这里不是实现类)别的接口时,由于默认方法的冲突,该接口同样需要覆盖重写该冲突了的默认函数。

public interface MyInterfaceAbstractC extends MyInterfaceAbstract,MyInterfaceAbstractB {
	@Override
	public default void methodDefault() 
	{
		MyInterfaceAbstract.super.methodDefault();//调用MyInterfaceAbstract的默认函数,格式与之前有差别
	}

}

最后说一下类和接口的区别:

1.类和类之间是单继承的,一个类只能有一个直接父类
2. 类和接口之间是多实现的,一个类可以实现多个接口
3.接口和接口之间是多继承的

你可能觉得接口和抽象类非常的相似,从而产生了迷惑,这里我挂一个我在csdn上看到的大佬的连接,里面详细的介绍了二者区别,我就不在这班门弄斧了。

链接: link.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值