抽象类和抽象方法
一个类中有一个以上的抽象方法,这个类就必须作为抽象类,用abstract修饰。
如果你继承一个abstract类并且想创建新类型的对象,你就必须提供父类抽象方法的实现。如果不提供所有的抽象方法的实现,那么编译器认为你新建的子类仍然是抽象类,强制你用abstract修饰子类。
可以用abstract修饰某个类而不引入任何抽象的方法。这表示虽然这个类提供抽象方法没意义,但是你不想那个类的实例被创建。
接口
接口实现了类似多重继承的概念。
和类一样,可以用public修饰interface,前提是接口的名字和文件的名字一样。如果不修饰接口,就是包访问权限,只能在同一个包中使用。
接口可以包含fields,这些字段是隐式的final和static的。
接口中的方法可以用public修饰,如果不加修饰,默认也是public的,因此实现接口的类对应的实现方法必须定义成public的,否则默认包权限,在继承树中降低了方法的访问权限,这是java编译器不允许的。
一个普通的子类可以upcast成普通父类,抽象父类,或者接口,这些行为是一样都被支持的。
实现接口的子类必须实现接口中的方法,一种可能的情况是这个子类还继承了一个父类,而父类中有个实现的方法的签名和接口中定义的一样。这是可以的。
java接口很好的解决了多重继承问题,像C++中的diamond继承问题就不会出现。
一个类只可以继承一个类,但是可以实现多个接口,如果一个类既继承类又实现接口,那么继承语句必须写在前面,实现语句写在后面,否则编译出错,多个接口用逗号分隔。
Arrays.toString(String [])
Arrays.toString(String [])将参数的String数组用逗号连接,两端加括号,然后返回这样一个String。
public class TestArraysd {
public static void main(String args[]){
String s = "few fefwe fwf ew ewf";
System.out.println(Arrays.toString(s.split(" ")));
}
}
输出:[few, fefwe, fwf, ew, ewf]
接口的继承
接口是可以继承接口的,只不过把父接口的方法包含了过来,要求实现的类必须将父接口和自己的方法都实现。
一个接口可以继承多个接口,这些接口用逗号分隔。
interface inter1 extends inter2,inter3,...
只有接口继承允许这样写,如果是类的话,extends只能跟一个类。
接口方法冲突
当接口与接口或者接口与父类中的方法签名相同但是返回值不同时,会出现编译错误:
class C{public int f(){return 1;}}
interface I1{
void f();
}
interface I2{
int f();
}
class A extends C implements I1{
}//wrong!! 返回值不兼容
interface I3 extends I1,I2{
}//wrong!! 返回值不兼容
Scanner
Scanner构造函数接收一个Readable接口作为参数,这个Readable是专门为Scanner引进的,有个 int read(CharBuffer)方法。返回读了多少字符,如果读到结尾就返回-1。
一个例子:
import java.nio.CharBuffer;
import java.util.Calendar;
import java.util.Random;
import java.util.Scanner;
public class TestScanner {
public static void main(String args[]){
Scanner scanner = new Scanner(new RandDoubleScanner(10));
while(scanner.hasNextDouble()){
System.out.println(scanner.nextDouble());
}
}
}
class RandDouble{
public double rand(){
Random r = new Random(Calendar.getInstance().getTimeInMillis());
return r.nextDouble();
}
}
class RandDoubleScanner extends RandDouble implements Readable{
private int count;
public RandDoubleScanner(int count){
this.count = count;
}
@Override
public int read(CharBuffer cb) {
// TODO Auto-generated method stub
if(count--==0){
return -1;
}
String result = rand()+" ";
cb.append(result);
return result.length();
}
}
输出:
0.1414165213358115
0.14087903070258168
0.1407894638315379
0.14105819424699162
0.14105819424699162
0.14096861247478665
0.14096861247478665
0.14052071851492298
0.14052071851492298
0.14052071851492298
read方法将读到的内容写入CharBuffer,返回读到的字符数。
这是一个适配器模式的例子,由于接口的引入,任何类都可以通过写一个适配器类来供Scanner读取,适配器继承这个类并实现Readable接口。可以看出接口是很有用的,如果不用接口用类的话就不好办了,因为不能多重继承,又不好改原来的类。
嵌套的接口
类中可以有接口的定义,类中定义的接口也有public,包,private等修饰符,对于private的,public的内部类也可以实现,但是这个内部类在类之外不具备接口的身份,因此实现私有接口可以强制内部类实现某些方法,但是又不允许内部类在外面被upcast。
在公有方法中返回指向私有的内部接口的引用时,唯一可以使用这个方法的返回值的情况是将返回的引用传递给有权限使用它的对象,即接口所在的类的对象。
接口中嵌套接口必须是public的,也是默认的,不能为private或其它,当实现一个接口时不一定要实现嵌套的接口,private的接口不能在所在的类外部被实现。
package test8;
class A {
interface B {
void f();
}
public class BImp implements B {
public void f() {
}
}
private class BImp2 implements B {
public void f() {
}
}
public interface C {
void f();
}
class CImp implements C {
public void f() {
}
}
private class CImp2 implements C {
public void f() {
}
}
private interface D {
void f();
}
private class DImp implements D {
public void f() {
}
}
public class DImp2 implements D {
public void f() {
}
}
public D getD() {
return new DImp2();
}
private D dRef;
public void receiveD(D d) {
dRef = d;
dRef.f();
}
}
interface E {
interface G {
void f();
}
// Redundant "public":
public interface H {
void f();
}
void g();
// Cannot be private within an interface:
// ! private interface I {}
}
public class NestingInterfaces {
public class BImp implements A.B {
public void f() {
}
}
class CImp implements A.C {
public void f() {
}
}
// Cannot implement a private interface except
// within that interface’s defining class:
// ! class DImp implements A.D {
// ! public void f() {}
// ! }
class EImp implements E {
public void g() {
}
}
class EGImp implements E.G {
public void f() {
}
}
class EImp2 implements E {
public void g() {
}
class EG implements E.G {
public void f() {
}
}
}
public static void main(String[] args) {
A a = new A();
// Can’t access A.D:
// ! A.D ad = a.getD();
// Doesn’t return anything but A.D:
// ! A.DImp2 di2 = a.getD();
// Cannot access a member of the interface:
// ! a.getD().f();
// Only another A can do anything with getD():
A a2 = new A();
a2.receiveD(a.getD());
}
}
使用接口实现工厂方法模式
package test2;
public class TestInters{
public void service(ServiceFactory sf){
Service s = sf.getService();
s.method1();
s.method2();
}
public static void main(String args[]){
new TestInters().service(new Service1Factory());
new TestInters().service(new Service2Factory());
}
}
interface Service{
void method1();
void method2();
}
interface ServiceFactory{
Service getService();
}
class Service1 implements Service{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("Service1 method1");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("Service1 method2");
}
}
class Service1Factory implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new Service1();
}
}
class Service2 implements Service{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("Service2 method1");
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("Service2 method2");
}
}
class Service2Factory implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new Service2();
}
}