面向对象的特性:封装,继承,多态
一、封装
封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装的好处:将变化隔离、便于使用、提高重用性、提高安全性。
封装的原则: 将不需要对外提供的内容都隐藏起来,把属性都隐藏提供公共方法对其访问。
例如:
1 public class Person { 2 int age; 3 void speak(){ 4 System.out.println("age="+age); 5 } 6 }
1 public class Test4 { 2 public static void main(String[] args) { 3 Person p=new Person(); 4 p.age=-20; 5 p.speak(); 6 } 7 }
此时Person类中没有将属性进行封装 ,Test类中对象p可以直接访问属性age,这就带来了安全性问题,如上述例子中age的值变成了负数。
如果我们将属性age私有化,并提供一个对外访问年龄的方法就可以避免出现安全性问题。
1 public class Person { 2 private int age; 3 public void setAge(int age){ 4 if(age>=1 && age<=150){ 5 this.age=age; 6 speak(); 7 } 8 else{ 9 System.out.println("年龄不合法"); 10 } 11 12 } 13 void speak(){ 14 System.out.println("age="+age); 15 } 16 }
1 public class Test4 { 2 public static void main(String[] args) { 3 Person p=new Person(); 4 p.setAge(20); //调用Person提供的方法 5 } 6 }
二 、继承
继承:是指一个类A继承类B,那么我们就把类B成为是类A的父类或者基类。继承可以使得子类具有父类的各种字段与方法,而不需要再编写同样的代码,在令子类继承 父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有字段和方法,使其获得与父类不同的功能,但是子类也可以定义属于自己的字段与方法。 继承的好处就是代码的重复使用,提高开发的效率。
下面代码演示继承:
1 public class Father { 2 String tool="computer"; 3 String language="vb"; 4 Father(){ 5 System.out.println("父类构造函数"); 6 } 7 void speak(){ 8 System.out.println("language....."+language); 9 } 10 void use(){ 11 System.out.println("tool....."+tool); 12 } 13 14 }
1 public class Son extends Father{ 2 String language="java"; 3 Son(){ 4 //super(); 子类的构造函数默认的第一行都有一句隐式的super(); 5 System.out.println("子类构造函数"); 6 } 7 void speak(String language){ 8 System.out.println("language....."+language); 9 } 10 }
测试类:
1 public class Test11 { 2 public static void main(String[] args) { 3 Son s=new Son(); 4 s.speak(); 5 s.speak("java"); 6 s.use(); 7 System.out.println(s.language); 8 9 } 10 }
结果为:父类构造函数 //子类的构造函数默认的第一行都有一句隐式的super();
子类构造函数
language.....vb //因为子类没有覆写父类的方法,所以该对象还是调用父类的方法。得到的结果是language.....vb
language.....java
tool.....computer //子类继承了父类的变量tool 方法 use()
java //子类中自定义的language 覆盖了从父类继承下来的language
java语言只支持单继承不支持多继承。
因为多继承会带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时子类对象不确定要运行哪一个。
java保留了这种机制并用另一种体现形式来表示-----多实现
假如支持多继承观察下面程序:
1 public class A { 2 void show(){ 3 System.out.println("a"); 4 } 5 } 6 7 public class B{ 8 void show(){ 9 System.out.println("b"); 10 } 11 } 12 13 public class C extends A,B { 14 C c=new C(); 15 c.show();//那么此时对象c不确定要运行哪一个show方法,所以会带来安全问题 16 }
对象c调用show()方法时就会出现安全问题,所以java不支持多继承。
三、多态
1.多态的体现:父类的引用指向了自己的子类对象,父类的引用也可以接收自己的子类对象。
2.多态的前提:必须是类与类之间有关系。要么继承,要么实现。通常还有一个前提:存在覆盖。
3.多态的好处:多态的出现很大的提高了程序的扩展性。
4.多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中的成员。
多态扩展性的体现:
1 public abstract class Animal { 2 public abstract void eat(); 3 public void sleep(){ 4 System.out.println("睡觉"); 5 } 6 }
1 public class Cat extends Animal{ 2 3 @Override 4 public void eat() { 5 6 System.out.println("吃鱼"); 7 } 8 public void catchMouse(){ 9 System.out.println("抓老鼠"); 10 } 11 }
1 public class Dog extends Animal{ 2 3 @Override 4 public void eat() { 5 System.out.println("啃骨头"); 6 7 } 8 public void kanMen(){ 9 System.out.println("看门"); 10 } 11 12 }
测试类一
public class DuoTai { public static void main(String[] args) { function(new Cat()); function(new Dog()); } public static void function(Animal a){//这里利用多态的特性,提高代码的复用,提高了扩展性。 a.eat(); } }
测试类二
1 public class DuoTai { 2 public static void main(String[] args) { 3 4 function(new Cat()); 5 function(new Dog()); 6 } 7 public static void function(Animal a){//这里利用多态的特性,提高代码的复用,提高了扩展性。 8 a.eat(); 9 if(a instanceof Cat){//instanceof:判断某一类型的引用指向的对象符合什么类型 10 Cat c=(Cat) a; //将a向下转型为Cat类型,只有经过向下转型后才能调用其特有的方法。 11 c.catchMouse(); 12 }else 13 if(a instanceof Dog){ 14 Dog d=(Dog) a;//同理向下转型为Dog类型 15 d.kanMen(); 16 } 17 } 18 }
多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有则编译通过,如果没有则编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单来说:成员函数在多态调用时,编译看左边,运行看右边。
在多态中 成员变量的特点:无论编译和运行都参考左边(引用型变量所属的类)
在多态中静态成员函数的特点:无论编译和运行都参考左边。