重载overloading
1.方法名相同,形参不同(包括参数顺序不同、类型不同、个数不同);
2.方法的返回值类型可同也可不同,所以不能用返回值类型来区分重载函数;
3.重载方法与被重载的方法可以抛出不同的异常;
4.重载体现了多态的特性:调用方法时根据传递的参数不同来决定具体调用那个重载方法,这就是多态性;
public class Dog { Dog() { this.bark(); } //bark()方法是重载方法 void bark(){ System.out.println(\"no barking!\"); this.bark(\"female\", 3.4); } //注意:重载的方法的返回值都是一样的, void bark(String m,double l) { System.out.println(\"a barking dog!\"); this.bark(5, \"China\"); } //不能以返回值区分重载方法,而只能以“参数类型”和“类名”来区分 void bark(int a,String n) { System.out.println(\"a howling dog\"); } public static void main(String[] args) { Dog dog = new Dog(); dog.bark(); dog.bark(\"male\", \"yellow\"); dog.bark(5, \"China\"); }
重写overriding
1.对从父类中继承来的方法进行重新定义(重写)——有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写;
2.重写的方法必须和被重写方法具有相同的方法名称、参数列表和返回类型,否则是重载而不是重写;
3.重写方法只能存在于具有继承关系中,且只能重写父类非私有的方法;
4.重写方法不能使用比被重写方法更严格的访问权限(public>protected>default>private);
5.重写方法一定不能抛出新的检查型异常或比被重写方法更加宽泛的检查型异常(Exception>IOException);
1. class Animal{ 2. String name; 3. void eat(){ 4. System.out.println("吃东西"); 5. } 6. void shout(){ 7. System.out.println("我是动物"); 8. } 9. } 10. 11. class Dog extends Animal{ 12. void eat(){ 13. System.out.println("狗啃骨头"); 14. } 15. void shout(){ 16. System.out.println("旺旺叫!"); 17. } 18. void eat(String food){ 19. System.out.println("吃:"+food); 20. } 21. } 22. class Demo{ 23. public static void main(String[] args){ 24. Dog d = new Dog(); 25. d.shout(); 26. d.eat(); 27. } 28. }
注意:重载和重写没有任何关系。
面向对象三个特性:继承、封装和多态。
继承extends
1、子类可以得到父类除了构造方法之外的所有属性和方法;
2、java中的类只有单继承,没有多继承,java中的多继承可以通过接口实现;
3、继承的本质在于抽象:类是对对象的抽象,继承是对某一批类的抽象;
4、定义一个类时若没有调用extends,则它的父类是java.long.Object;
5、不同的叫法:超类,父类,基类,子类,派生类;
6、 继承也可以换用组合,组合依然可以实现代码复用。不同点:
is-a关系:使用继承;
has-a关系:使用组合;
封装encapsulation
1、封装也称隐藏;良好的封装,便于修改内部代码,可进行数据完整性检测。
2、隐藏对象内部的复杂性,只对外公开简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性。
3、 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
低耦合:仅仅暴露少量的方法给外部使用;
4、类的属性的处理:
1.一般使用private——除非本属性确定会让子类继承;
2.提供相应的get/set方法来访问相关属性。方法通常是public,从而提供对属性的读取操作。
希望其他类调用的方法当然是public;
使用访问控制符,实现封装:
|
同一个类 |
同一个包中 |
子类 |
所有类 |
private |
# |
|
|
|
Default 即不加修饰符 |
# |
# |
|
|
protected |
# |
# |
# |
|
public |
# |
# |
# |
# |
多态
1.多态就是同一操作(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果;
2.实现多态的技术:动态绑定:在执行期间判断所引用对象的实际类型,根据其实际的类型调用相应的方法;说白了就是通过接口实现的多态,继承父类进行方法重写,同一个类中进行方法重载。
3.方法多态的体现有3个必要条件:很重要。
1)要有继承;2)要有方法重写;3)父类引用指向子类对象;
public class A { public String show(D obj){ return "A and D"; } public String show(A obj){ return "A and A"; } } class B extends A{ public String show(B obj){ return "B and B"; } public String show(A obj){ return "B and A"; } } public class Test { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); D d = new D(); System.out.println(a1.show(b));//结果:A and A System.out.println(a1.show(d)); //结果:A and D System.out.println(a2.show(b)); //结果:B and A System.out.println(a2.show(d)); //结果:A and D System.out.println(b.show(b)); //结果:B and B System.out.println(b.show(d)); //结果:A and D } }
面向对象的五大原则:
1.单一功能原则:每个类型(包括接口和抽象类)功能要求单一,只负责一件事情;
2.开放封闭原则:一个模块在更改性方面应该是封闭的,在扩展性方面应该是开放的。比如一个网络模块,原先只有服务端的功能,现在我要加入客户端的功能。
3.替换原则:子类可以替换父类,并出现在父类能出现的任何地方;
4.依赖倒置原则:要依赖于抽象,不要依赖于具体。简单的讲:就是要面向抽象、面向接口编程,不要对实现进行编程,否则降低了客户与实现模块之间的耦合度;
在面向过程开发中,上层依赖下层,当下层剧烈的发生变化时,上层也要发生变化,这样就导致了模块之间的耦合性太高,复用性降低。
面向对象解决了该问题:一般情况下,抽象变化的几率很小,让用户程序依赖于抽象,实现细节也依赖于抽象,即使实现细节不断的变化,只要抽象不变,客户端程序就不用去变化;
5.接口隔离原则:不同的模块要通过接口隔离开,而不是通过具体类强耦合;