问题
5个更好的设计步骤
3个多态的技巧
8种让程序更有适应性的方法
4项对继承的建议
继承
子类使用父类的方法
子类可以override父类的方法
子类继承父类
可以添加新的实例变量,新的方法
可以重写原来的方法
子类覆盖父类的方法后,其方法名和参数完全一样
当调用该方法时,会调用最低阶的那个方法,也就是子类的方法,如果子类没有覆盖过父类的方法,则会调用父类的方法
如何区别覆盖和重载?
覆盖:
参数必须要一样,且返回类型必须要兼容,不能降低方法的存取权限
重载:
返回类型可以不同
不能只改变返回类型,参数也得变
可以更改存取权限
如何判断两个类的继承关系?
使用IS - A测试
如果一头狮子是一个动物,那么狮子继承自动物
# IS -A 是一个单向关系
【其实是一种包含关系,属于关系】
存取权限
父类可以使用存取权限来决定那些可以被继承
private default protected public
4项对继承的建议
当某个类会比其父类更具有特定意义是使用继承
在方法程序应该被多个相同类型的类所共享时使用继承
两者间的关系对于继承结构不合理不使用继承
两者不能通过IS -A测试不使用继承
继承的意义?
减少很多重复代码(放到了父类中)
修改时修改的代码少(修改父类中的方法,子类中的方法自动更新,不过父类中的修改要注意,如果修改了方法的参数类型等,那么子类也得修改,要不会造成破坏,子类无法使用父类的方法)
这里为了防止破坏需要注意参数必须要一样,且返回类型必须要兼容,不能降低方法的存取权限(例如:不能将public方法修改为private方法)
多态
一般情况下对象和对象的引用是同一类型
比如: Dog mydog = new Dog();
但在多态下,引用类型可以是实际对象的父类
比如: Animal mydog = new Dog();
对于一个父类,任何extends过这个类的对象都可以赋值给这个引用变量,
也就是说,该父类的子类所生成的对象都可以赋值给该父类声明的一个引用变量
(1)甚至可以声明一个多态数组,用来存储属于同意父类的不同子类对象
比如:
Animal[] animals = new Animal[5];
animal[0] = new Dog();
animal[1] = new Cat();
animal[2] = new Bird();
……
#注意:这里使用圆点运算符调用方法时,只能调用引用类型的方法,即如果子类覆盖了父类的所有方法,那么使用引用类型调用方法时就可以按子类覆盖过的方法进行,如果引用类型中没有某个方法则不能使用。
(2)如果将父类声明的引用变量作为参数传递给方法,在方法中使用该引用变量的方法,那么使用时将会根据赋值给引用变量的子类方法的不同而产生不同的效果
这样就算再增加子类,这一段程序也不需要修改,只是赋值给父类引用变量的子类不同了而已。
如何防止类被继承?
存取权限
使用final修饰符
让类只拥有private的构造程序
要使用多态,需要接口,很多Java的功能没有接口机制就无法使用
那么接口是什么?
接口是纯抽象的类
那什么是抽象类?
无法被初始化的类
前面的Animal类就是一个抽象类,他是根据多种动物的共同特点构造出来的类,他可以被用来继承和产生多态,不过Animal这个类到底应该是怎样的,他没有具体形态,他是被抽象出来的,那么能不能初始化呢?
最好不要初始化,抽象类代表没有人能够创建出该类的实例(?)
不过依旧可以将抽象的类型作为引用类型
如何防止一个抽象类被初始化?
在类的前面加上abstract关键字
抽象的方法?
除了对类标记为abstract,方法也可以标记为abstract,抽象的类代表此类必须要被extends过,抽象的方法代表该方法一定要被覆盖过
【抽象的方法没有实体,没有方法的内容,直接以分号结束】
【抽象方法必须在抽象类中,非抽象类不能有抽象的方法】
抽象的方法的意义:
有时子类具有同一特点,但是无法在父类中给出相应程序代码,需要在不同的子类中自己实现,抽象的方法就是提前定义一个子类共同使用的协议,这样不同的子类就可以使用同一方法实现不同的状态或者行为,这不就是多态吗。
接口:
纯抽象类的好处之一是他是一张白纸(在没有static变量的情况下),其方法(抽象)由子类去实现,不会出现致命方块(一个子类继承的两个父类来自于同一个类,可能会导致数据的二义性)的问题,
使用接口就可以继承一个以上的来源,可以根据需求组合出不同的层次
使用
定义接口 interface
使用接口 implements
在子类中如何调用父类的方法?
super