面向对象高级程序设计基础知识回顾

综述:本章讲述Java面向对象技术的另外两个特点,多态和继承,以及由继承机制派生出来的接口技术和抽象类等概念。

5.1 继承

1)子类可以继承父类中权限设置为public,protected和default的成员变量和方法;但是不能继承访问权限为private类型的成员变量和方法。
2)子类对象创建的实质是在调用子类构造函数函数之前首先调用父类构造函数,默认为默认构造函数super,且通常是隐式调用;当然也可以通过super显式调用其他重载构造函数。
3)子类可以通过super关键字访问父类的public,protected,default类型的成员和方法,验证如下:
这里写图片描述

4)成员变量的隐藏和方法的重写:如果子类成员变量与父类成员变量同名,那么子类成员隐藏了父类成员(而不管其类型);如果子类中的方法名,参数部分和父类一模一样,那么称子类重写了父类的成员函数(而不管其返回值类型,因为此时返回类型被要求一致)。验证如下:
这里写图片描述
注意,这里子类C中的String类型的a隐藏了父类B的int类型的a,并且子类中的sayHello方法被重写,在该方法中,通过super关键字调用了父类的sayHello方法。
所谓的隐藏,并不是指子类的a成员取代了父类的a成员,导致子类对同名成员的访问的指向父类中的同名成员(即不能错误的认为子类中的sayHello方法访问的成员a为String a=”xcl”;其仍然是int a=10;),而是说明父类对子类的同名成员的访问需要使用super.a来访问这样一种访问方式。

5.2 对象的上转型对象(对象的装箱与拆箱)

所谓对象的上转型对象是指对象是由子类负责创建的,但是对象的上转型对象会失去原对象的一些属性和功能,其特点如下:
1) 上转型对象不能操作子类中新增的成员和方法,因为静态的看来其毕竟是一个父类类型的对象。但是动态的执行的时候,如果子类重写了父类的方法,由于多态的性质,该上转型对象调用的却是子类的重写方法。这也可以被视作是对多台的支持。
这里写图片描述
2) 不要将父类创建的对象和子类创建的上转型对象混淆,他们是有区别的。
3) 上转型对象在Java中是常见的,不仅父类可以接受子类的上转型对象,接口和抽象类也可以接受(实现了接口的类的,抽象类派生的子类的)上转型对象。验证如下:
这里写图片描述
4) 上转型对象可以重新下转型为原来的类型的对象,从而恢复正常的成员和方法。

5.3 多态性

在Java语言中,多态性主要体现在两方面,即编译时多态(方法重载)和运行时多态(上转型对象调用重写方法)。

方法重写时应该遵循的原则如下:
1) 不能比父类中该方法拥有更加严格的权限。
2) 可以比父类产生更多异常,更少异常,或更改异常类型,或者说与异常无关(但是书上说不能比被重写的方法产生更多的异常,经过验证发现是错的)。
这里写图片描述

5.4 抽象类和抽象方法

在Java语言中,用abstract关键字修饰一个类时,这个类叫做抽象类。一个抽象类只关心他的子类是否具有某种功能,并不关心该类的具体实现,功能的具体实现是由子类负责实现的。

1) 与final类和方法相反,abstract类必须被继承,abstract方法必须被重写。
2) Abstract方法只能定义在abstract类里面,abstract类却可以包含非abstract成员和非abstract方法。
3) Abstract类无法被实例化,而只能被继承。

5.5 接口

接口的定义和申明如下:
[public] interface 接口名 [extends 父接口列表]{
[public][abstract]方法声明;(接口中的方法都是抽象的和公共的)
[public][static][final]常量声明;
}
注意:接口继承父接口使用的是extends关键字而不是implements关键字,这是显而易见的,因为implements是指类实现接口,extends是指继承而不必实现。

1) 子接口可以继承父接口的一切方法和常量。
2) 通常接口以able或ible结尾,表明接口可以完成一定的行为,例如Runnable接口。
3) 接口体的定义包括常量定义和方法定义两部分。
4) 在接口中的声明中,方法默认具有public,abstract属性;常量默认具有public,static,final的属性。
5) 在类中实现接口时,方法的名字,返回类型,参数个数和参数类型必须与接口中的完全一致。
6) 接口中方法默认为public,所以类在实现接口的时候必须用public修饰,因为不能降低方法的可见性。
7) 从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而不包含方法的实现和变量的定义。类似于public abstract class,但是制定声明方法和定义常量。
8) 接口的实质就是常量定义和方法声明的集合。
9) 接口技术的优点是:通过接口可以了解对象交互的界面而不需要了解对象所对应的类。
10) 关于接口技术的分析如下:

package a;

import java.io.FileNotFoundException;
import java.io.IOException;

interface outputible{
    public abstract void output(String s);
    public abstract void output(String s,int a)throws IOException,FileNotFoundException;
}

interface outputable{
    public static final float PI=3.1415926f;
    public static final float E=2.8f;
    public abstract void output() throws IOException;
    public abstract void output(String s) throws IOException;
}

class B implements outputible{

    @Override
    public void output(String s) {
        // TODO Auto-generated method stub
    }

    @Override
    public void output(String s, int a) throws IOException, FileNotFoundException {
        // TODO Auto-generated method stub
    }

}

class C extends B implements outputable{

    @Override
    public void output() throws IOException {
        // TODO Auto-generated method stub
        System.out.println("PI="+C.PI);
    }

}

public class A {
    public static void main(String[] args) {
        try {
            new C().output();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

在以上接口outputible和outputable的定义中,outputable中定义类常量,所以在class C实现了接口outputable时,可以通过C.PI来引用继承的静态常量,从而也进一步证实在接口中定义的敞亮具有public static final属性。同时接口outputible和outputable接口具有重复定义的方法,所以当接口outputable继承outputible接口的时候就会出现两个问题,其一是output(String s)方法会被认为是重写;其二是output(String s,int a)会产生冲突,但是类B实现outputible之后被C继承,切C实现了outputable,那么就会解决所有问题,但是这种接口设计和继承的关系是十分不合理的。应该尽量避免这种接口设计方法。

5.6 枚举类型

枚举就是一种被命名的整形常数集合。例如表示星期的“周一,周二,…,周日”就是枚举。

1) 枚举的定义:
Enum 枚举名{
标识符[=整形常数|(此括号表示自构造)],标识符[=整形常数|(此括号表示自构造)],
…,标识符[=整形常数|(此括号表示自构造)];//经过验证,不能赋值
//可以有private变量
//可以有private构造函数
}
2) 枚举类型成员全部被隐式声明为公有静态成员(表示对枚举值得引用只能通过“枚举名.枚举成员”的方法来引用),且其类型为该枚举类型。类似于下列结构:
这里写图片描述

3) 尽管枚举可以创建枚举类型的变量,但是枚举变量不能使用new关键字来创建实例,而只能赋值枚举预定义常量。
4) 枚举可以用==来判断,也可用于switch语句。
5) 由于枚举其实就是一个特殊的类,所以,枚举可以添加构造函数,添加实例变量和实例方法,甚至实现接口。每一个枚举常量就是他的枚举类型的一个对象,因此如果为枚举定义了构造函数而没有默认构造函数,那么每定义一个枚举常量就要调用一个构造函数进行自构造。
6) 特别注意枚举类型的两个静态方法,这一点很好的证明了枚举其实是一种特殊的类,所以枚举可以实现接口。其中是返回所有的枚举成员:

enum AA[] all_member=A.values();
A a=A.valueOf(“member1”);

7) 枚举有两个限制:枚举不能是子类,枚举不能是父类。

5.7 Annotation

1)从JDK5.0开始提供元数据的功能(即Annotation,注释)。
2)Annotation可以附加在package,class,method,field等上,相当于给他们添加了额外的辅助信息。
3)常用的Annotation有@Override,@Deprecated,@SupperWarnings
4)可以自定义Annotation,使用@interface关键字定义Annotation,其声明和一般的接口声明类似,区别在于方法参数不必有参数或者异常声明;方法声明的返回值被定义在下列类型:primitives,String,Class,enums,Annotations和前面类型的数组。
例如:
Public @interface 注解名{
String value() default “hahaha”;//声明类似于接口,故无方法体。
}
4) 要深入理解Java注解,请看这篇博客
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
经典Annotation的例子,请看该博客的水果实例,如果需要处理注解,请看该篇博客的下篇关于注解的处理:
http://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

5.8 内部类和匿名类

Java语言,对于内部类有如下定义:
1) 在一个类或者一个接口中声明一个类
2) 在一个类或者一个接口中声明一个借口
3) 在一个方法中声明一个类
4) 类和接口的声明和一任意层次的嵌套

内部类有如下特性:
1) 一般用在包含他的类或语句块之内,在外部引用他的时候必须给出完整的名称,名称不能与包含他的类相同。
2) 可以使用包含他的外部类的静态成员变量和实例成员变量,也可以使用它所在方法的局部变量。
3) 可以定义为abstract,用于被其他内部类继承。
4) 可以声明为protected或private。
5) 若被声明为了static,则变成了顶层类,则不能使用所在类的成员变量,也不能使用局部变量。
6) 如果在类内声明了static成员,则该类必须被声明为static。
7) 内部类相当于外部类的成员,所以外部类只能通过内部类的实例访文内部类的成员;内部类对于外部类的访问,可以直接访问其静态变量和成员变量。

关于匿名类的一个实例如下:

package a;


class B{
    interface outputable{
        public abstract void output();
    }

    private void output(outputable otp){
        System.out.println("----------------------------");
        otp.output();
        System.out.println("----------------------------");
    }

    void display(){
        output(new outputable(){

            @Override
            public void output() {
                // TODO Auto-generated method stub
                System.out.println("this is a test");
            }
        });
    }

}


public class A {
    public static void main(String[] args) {
        new B().display();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值