学习笔记20170627
来源:互联网 发布:拳皇14键盘优化 编辑:程序博客网 时间:2024/05/19 17:47
一、面向对象的三大特性
1、封装。它指的是将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。(例如通过set、get方法来访问)
2、继承。Java的继承具有单继承的特点,每个子类只有一个直接父类。子类扩展了父类,将可以获得父类的全部成员变量和方法,
3、多态。Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。
例如:
class BaseClass{
public int book = 6;
public void base(){
System.out.println("父类的不同方法");
}
public void test(){
System.out.println("父类的被覆盖的方法");
}
}
public class SubClass extends BaseClass{
//重新定义一个book实例变量隐藏父类的book实例变量
public String book = "轻量级Java EE企业应用实战";
public void test(){
System.out.println("子类的覆盖父类的方法");
}
public void sub(){
System.out.println("子类的普通方法");
}
public static void main(String[] args){
//下面编译时类型和运行时类型完全一样,因此不存在多态
BaseClass bc = new BaseClass();
//输出6
System.out.println(bc.book);
//下面两次调用将执行BaseClass的方法
bc.base();
bc.test();
//下面编译时类型和运行时类型完全一样,因此不存在多态
SubClass sc = new SubClass();
// 输出"轻量级Java EE企业应用实战"
System.out.println(sc.book);
// 下面调用将执行从父类继承到的base()方法
sc.base();
// 下面调用将执行当前类的test()方法
sc.test();
// 下面编译时类型和运行时类型不一样,多态发生
BaseClass ploymophicBc = new SubClass();
// 输出6——表明访问的是父类对象的实例变量
System.out.println(ploymophicBc.book);
// 下面调用将执行从父类继承到的base()方法
ploymophicBc.base();
// 下面调用将执行当前类的test()方法
ploymophicBc.test();
// 因为ploymophicBc的编译时类型是BaseClass
// BaseClass类没有提供sub()方法,所以下面代码编译时会出现错误
// ploymophicBc.sub();
}
}
当把一个子类对象直接赋给父类引用变量时,例如上面BaseClass ploymophicBc = new SubClass();,这个ploymophicBc引用变量的编译时类型是BaseClass,而运行时类型是SubClass,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征,这就可能出现:相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态。
二、继承与组合
继承是实现类复用的重要手段,但继承带来了一个最大的坏处:破坏封装。相比之下,组合也是实现类复用的重要方式,而采用组合方式来实现类复用则能提供更好的封装性。
例如:
Bird b = new Ostrich();
b.fly();
对于上面代码声明的Bird引用变量,因为实际引用一个Ostrich对象,所以调用b的fly()方法时执行的不再是Bird类提供的fly()方法,而是Ostrich类重写后的fly()方法。
为了保证父类有良好的封装性,不会被子类随意改变,设计父类通常应该遵循以下规则:
①尽量隐藏父类的内部数据。尽量把父类的所有成员变量都设置成private访问类型,不要让子类直接访问父类的成员变量。
②不要让子类可以随意访问、修改父类的方法。父类中那些仅为辅助其他的工具方法,应该使用private访问控制符修饰,让子类无法访问该方法;如果弗雷中的方法需要被外部类调用,则必须以public修饰,但又不希望子类重写该方法,可以使用final修饰符来修饰该方法;如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,则可以使用protected来修饰该方法。
③尽量不要在父类构造方法中调用将要被子类重写的方法。
例如:
class Base{
public Base{
test();
}
public void test(){ //①号test()方法
System.out.println("将被子类重写的方法");
}
}
public class Sub extends Base{
private String name;
public void test(){ //②号test()方法
System.out.println("子类重写父类的方法,"+"其name字符串长度"+name.length());
}
public static void main(String[] args){
//下面代码会引发空指针异常
Sub s = new Sub();
}
}
当系统试图创建Sub对象时,同样会先执行其父类构造方法,如果父类构造方法调用了被其子类重写的方法,则变成调用被子类重写后的方法。当创建Sub对象时,会先执行Base类中的Base构造方法,而Base构造方法中调用了test()方法——并不是调用①号test()方法,而是调用②号test()方法,此时Sub对象的name实例变量时null,因此将引发空指针异常。
到底何时需要从父类派生新的子类呢?不仅需要保证子类是一种特殊的父类,而且需要具备以下两个条件之一:
①子类需要额外增加属性,而不仅仅是属性值的改变。例如从Person类派生出Student子类,Person类里没有提供grade(年级)属性,而Student类需要grade属性来保存Student对象就读的年级,这种父类到子类的派生就符合Java继承的前提;
②子类需要增加自己独有的行为方式(包括增加新的方法或重写父类的方法)。例如从Person类派生出Teacher类,其中Teacher类需要增加一个teaching()方法,该方法用于描述Teacher对象独有的行为方式:教学。
- 学习笔记20170627
- 学习笔记?
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- 学习笔记
- chrome浏览器的跨域设置——包括版本49前后两种设置
- java多线程和Python多线程
- 百度百科对“设备独立性的解释
- Python编程之http简介
- HDU 1234 JAVA
- 学习笔记20170627
- 初学的一些操作防止遗忘
- Kickstart Practice Round 2017 Problem A. Country Leader
- 【Nginx】配置Nginx的负载均衡
- [leetcode]242. Valid Anagram
- 应用echarts.js的小小总结
- 读取系统的联系人
- jfinal 定时缓冲任务
- 使用Topshelf创建Windows 服务