欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。

教程  Java语言学习—第九章 抽象类与接口[Java基础]

Java 原创 1056 0评论

内容概要:

1.抽象类 

2.final关键字 

3.接口 

4.Cloneable接口

5.Enumeration接口

 

1.抽象类

请注意下面noAction()方法。此方法无方法体,并且前面出现abstract关键字。

public abstract void noAction(); //body({....}) 

noAction()方法无方法体,因而也没有具体的动作。我们将此方法称为抽象方法,在此类方法前面有abstract关键字。

包含抽象方法的类被称为抽象类(abstract class)。在定义抽象类时,要在class前面插上abstract关键字

abstract class Myclass {...............................//Myclass类是abstract类
int myInt;
public abstract void noAction();......................//x1,抽象方法
public int getMyint(){.....................................//非抽象方法
return myInt;
}
}

包含抽象方法的类,即抽象类无法创建对象,因为抽象方法未定义任何具体的动作。

抽象类无需定义方法体,在某些场合下,让子类继承并覆盖它,子类就能完成需要的功能,但要注意的是:继承了抽象类的子类一定要覆盖所继承的抽象方法,否则子类也将称为抽象类。

abstract class Shape{.................................//抽象类
double area;
public abstract void draw();.................................//抽象方法
public double area(){
return area;
}
}
class Rectangle extends Shape{.................................//继承
double d,h;
public Rectangle(int a,int b){.................................//构造函数
d=a;h=b;area=d*h/2;
}
public void draw(){.................................//覆盖继承的抽象方法
System.out.println("画三角形");
}
}
class Rectangle2 extends Shape{.................................//继承
double l,w;
public Rectangle2(int a,int b){.................................//构造函数
l=a;w=b;area=l*w;
}
public void draw(){.................................//覆盖抽象方法
System.out.println("绘制矩形");
}
}
public class Abstract1{
public static void main(String[] args) {
Shape tr=new Rectangle(10,20);
Shape re=new Rectangle2(10,20);
System.out.println(tr.area());
tr.draw();
System.out.println(re.area());
re.draw();.................................//tr与re都是用画()方法绘制
}
}

//结果:100.0 画三角形 200.0 绘制矩形

注意:抽象方法不能为private或static所修饰,abstract方法是子类应覆盖的方法,所以在抽象类中声明时不要使用private关键字。static方法在不创建对象时也可以被调用,所以其方法体(body)应该被定义。若无方法体,也就不能以“类.方法名()”的形式对其调用,所以abstract方法(无方法体)不能用static关键字修饰。

 

2.final关键字

final为:最后,最终,终端之意。final关键字可以用来修饰变量、方法和类。

public final int a = 10;//表示a为常量(constant)。即首次给a赋值后,以后不能再给它赋其他的值。

常量一般为所有对象所共有,所以把常量声明为static的情形也很多。public static final double PI=3.141592654358979323846;

PI值保持不变,并为所有对象共有。


static变量:static成员变量在不创建对象时也可以使用,并为所有对象共有。普通成员变量(non-static)只有在创建了对象后,才能使用。

最终方法:final关键字也可以出现在方法前面,如下所示:public final void f(){...} ,我们将此方法称为最终方法,继承含括最终方法的子类不能覆盖该最终方法。若子类可以改变最终方法,从而改变其功能,将会导致致命的错误出现。最终方法用以保护方法的功能,禁止对方法功能作出修改。


final关键字也可以出现在类前,意味着其他类无法继承该类,System类与String类就不能被继承改变其功能,所以可以定义成final类。

final class Final_1{
public static final double PI=3.14;
public final void fmethod(){
System.out.println("不能覆盖此方法");
}
}
public class Final extends Final_1{................//final类不能被继承
public void fmethod(){............................//final方法不能被覆盖
System.out.println("错误");
}
public static void main(String[] args) {
PI=3.15;............................................//不能改变常数值
}
}

 

3.接口

interface字面含义为界面,它是两个对象相互作用的接口。

在Java接口中,所有方法都是抽象的,所有变量也都是static常量,接口本身就是一种约束。

public interface MyInter{
public static final int MAX=100;.............//x1
public int MIN=1;............................//x2
public abstract void method();.............//x3
public void method2(int a);................//x4
}

接口中所有变量都是静态的(static)和最终的(final)。然而,x2行的变量MIN之前并没有static与final关键字,这并不会对变量MIN的静态性与最终性产生任何影响。

接口中所有的方法都是抽象的,x3与x4行的方法都是抽象的,关键字abstract可以省去。


由于接口所有方法都是抽象的,所有实现此接口只有全部覆盖了接口的全部方法,才能创建对象。注意,我们把继承接口称为实现接口。使用关键字implements,而不是extends。

与抽象类相比,接口更具有抽象性,实现接口的类必须实现接口中所有抽象方法。与继承类似,实现也意味着实现接口的类会继承接口的所有成员。

interface MyInter{.........................................//接口
public static final int MAX=100;
public static final int MIN=1;
public void method1();
public void method2(int a);
}
public class Interface1 implements MyInter{....................//实现MyInter接口
public void method1(){.........................................//x1,覆盖method1()方法
System.out.println("method1 override");
}
public void method2(int a){.........................................//x2,覆盖method2()方法
System.out.println(a+"method2 override");
}
public static void main(String[] args) {
Interface1 ob=new Interface1();
ob.method1();.........................................//调用覆盖后的方法method1()
ob.method2(123);......................................//调用覆盖后的方法method2()
System.out.println(Interface1.MAX);...................//Interface1继承了MAX常量
System.out.println(MyInter.MIN);......................//可以在不创建对象的条件下,使用static变量
}}
在实现接口时,必须覆盖所有抽象方法。
在类的继承中,只能单重继承,而实现接口时,一次可以实现多个接口,这些接口之间用逗号分开。
interface MyInter1{........................................//接口1
public void method1();
}
interface MyInter2{........................................//接口2
public void method2();
}
public class Interface2 implements MyInter1,MyInter2{//同时实现接口1,接口2。(Interface2必须实现两个接口中的所有抽象方法)
public void method1(){........................................//x1,覆盖Myinter1的方法
System.out.println("method1 voerride");}
public void method2(){........................................//x2,覆盖MyInter2的方法
System.out.println("method2 voerride");}
public static void main(String[] args){
Interface2 ob=new Interface2();
ob.method1();
ob.method2();
}
}

也可以一次实现3个或3个以上的接口:

class Interface2 implements MyInter1,MyInter2,MyInter3.....{....}

我们还可在继承类的同时实现接口

public class Interface3 extends Myclass implements Myinter1,Myinter2{...}

接口也可以继承接口。

interface MyInter1{
public void method1();}
interface Myinter2 extends Myinter1{ ...........//接口继承接口,用extends
public void method2();
public class Interface4 implements Myinter2{....//类实现接口,用implements
public void method1(){System.out.println("method1 voerride");}..//覆盖接口的抽象方法
public void method2(){System.out.println("method2 voerride");}..//覆盖接口的抽象方法
public static void main(String[] args){
Interface4 ob=new Interface4();
ob.method1();
ob.method2();
}}

Myinter2接口继承了Myinter1接口,所有拥有了两个抽象方法method1()和method2(),再Interface4实现Myinter2接口后,必须覆盖Myinter2中的两个抽象方法。


接口中的方法不能使用private与protected关键字修饰。不能用private是因为接口中的方法必须要被覆盖,protected关键字修饰的方法只允许子类进行访问,但是接口不能通过继承进行实现,所以我们用public来修饰接口方法。

 

4.Cloneable接口

我们学过引用传递调用知识,若方法的形式参数为一引用,那么它就可以引用由参数传递过来的对象。而有时我们要复制对象,并将对象的副本传递给方法。我们把复制对象的过程叫克隆。

void f(SomeObject ob){.....}//某方法

SomeObject ob=new SomeObject();//某对象

f(ob的副本); //将ob的副本传递给参数


在Java中产生副本时,遵守下列约定。

若想产生自身的副本:

1.创建该对象的类时必须实现Cloneable接口。

2.创建该对象的类必须覆盖Object类的clone()方法。

public class Cloneable1 implements Cloneable{
String s; int a;
public Cloneable1(String s,int a){
this.s=s; this.a=a;
}
public Object clone(){.................................//返回自身副本,覆盖
try{
return super.clone();.................................//调用Object类的clone()方法
}catch(CloneNotSupportedException cse){}
return null;
}
public static void main(String[] args) {
Cloneable1 ob1=new Cloneable1("abce",10);
Cloneable1 ob2= (Cloneable1) ob1.clone();.................................//生成ob1的副本
System.out.println("原本:"+ob1.hashCode());
System.out.println("副本:"+ob2.hashCode());
System.out.println("原本:"+ob1.s+ob1.a);
System.out.println("副本:"+ob2.s+ob2.a);
}}

结果:

原本:29855319

副本:5383406

原本:abce10

副本:abce10

 

5.Enumeration接口

实现了Enumeration接口的对象内部持有给定的元素(element),需要时,可将它们顺利的取出来。

Enumeration接口位于java.util包中,内有两个方法。如下:

boolean hasMoreElements();检查内部是否存在元素,若存在,返回true,否则返回false。

Object nextElement();返回下一个元素。

 

问题思考

(1)在面向对象程序设计中,使用常量(final)的原因何在?若不使用常量,会出现一些什么问题呢?

(2)抽象类与接口在作用上有何差异?请思考。

(3)图像类(shape)应该定义成接口还是抽象类呢?说明令人信服的理由。


转载请注明: ITTXX.CN--分享互联网 » Java语言学习—第九章 抽象类与接口[Java基础]

最后更新:2018-09-28 10:52:37

赞 (2) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽