小谈一下面向对象的3大特征:封装、继承、多态
Java是纯面向对象的编程语言,面向对象的思想其实很简单,就是”anything is Object”,即“万事万物皆为对象”。面向对象最重要的一点,就是要知道面向对象的思想符合人们客观看待世界的规律,是正常而客观的。
面向对象技术主要有以下特点:
1)对象是人们对现实世界中具有某些相同特性的事物的抽象;
2)对象中包含了一定的属性和方法;
3)对象的属性用来表示其具有的相同信息;
4)对象之间的作用可以通过接口完成。
从而总结出面向对象思想的有点:
*单个对象功能专一、简单,而多个对象各司其职、各尽其能,可以健壮地完成软件的要求;
*弱耦合性,对象的耦合性是对象与对象之间、对象与系统之间的联系。对象的耦合性要尽可能的弱;
*可重用性,对象的功能越简单,耦合性越弱,可可重用性就越好;
*可扩展性,当系统中加入新的对象或替换原来的对象时,系统仍然可以保持稳定。
封装:是构建其他代码的基础,没有封装,程序代码就无从谈起,也许是由于翻译的问题,好多人都对封装这个概念很模糊,其实封装就相当于包装,是最常见的。在面向对象的软件中,封装比比皆是。
包结构式一个封装,封装了若干个类;定义的类也是封装,封装了属性和方法;定义的方法也是一个封装,封装了此方法的所有操作,对外部提供公开的接口。所以说,封装在面向对象的软件开发中随处可见。
类的封装时学习的重点,要对类进行规范的封装,有两个层次要注意:
1)对于类的封装,要根据系统的实际需求来决定属性和方法是应该公开还是应该私有,一切从实际出发,不要盲目地全盘私有。
2)对于一般的模式,特别是对应现实中某样东西的数据原型类,属性应该私有。读取和更改对象的属性可以调用公开的访问方法,如getXxx()和setXxx()方法,这些方法可以对参数的数值进行安全检查。
下面看一个封装的小例子吧,代码如下:
package blog; public class Person { private String name; private int age; private boolean gender; private Person partner; public Person() { super(); // TODO Auto-generated constructor stub } public Person(String name, int age, boolean gender, Person partner) { super(); this.name = name; this.age = age; this.gender = gender; this.partner = partner; } public boolean isOverAgeForMarry(){ if(this.gender && this.getAge()>=23){ return true; }if(!this.gender && this.getAge()>=21){ return true; } return false; } public boolean marry(Person p){ if(this.gender == p.gender){ System.out.println("根据国家法律,暂时不允许同性结婚!"); return false; }if(this.partner != null || p.partner != null){ System.out.println("一方已结婚,再结婚构成重婚罪"); return false; }if(!this.isOverAgeForMarry() || !p.isOverAgeForMarry()){ System.out.println("未到结婚年龄!"); return false; } System.out.println("恭喜!"+this.name+"和"+p.name+"结婚成功"); this.partner = p; p = this.partner; return true; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } public Person getPartner() { return partner; } public void setPartner(Person partner) { this.partner = partner; } }
测试程序如下:
package blog; public class MarryTest { public static void main(String[] args) { Person p5 = new Person("许仙",24,true,null); Person p6 = new Person("白素贞",23,false,null); Person p7 = new Person("小青",18,false,null); System.out.println("小青和许仙申请结婚,得到答案是:"); p5.marry(p6); System.out.println("白素贞和许仙申请结婚,得到答案是:"); p5.marry(p6); p7.setAge(25); System.out.println("小青现在已经"+p7.getAge()+"岁了,申请和许仙结婚,得到答案是:"); p7.marry(p5); p5.setPartner(null); System.out.println("许仙离婚了,成了自由人,申请和小青结婚,得到答案:"); p5.marry(p6); } }
输出结果如下:
小青和许仙申请结婚,得到答案是: 恭喜!许仙和白素贞结婚成功 白素贞和许仙申请结婚,得到答案是: 一方已结婚,再结婚构成重婚罪 小青现在已经25岁了,申请和许仙结婚,得到答案是: 一方已结婚,再结婚构成重婚罪 许仙离婚了,成了自由人,申请和小青结婚,得到答案: 恭喜!许仙和白素贞结婚成功
继承:在软件的编码过程中,继承是面向对象的若干种关系的基础。正是因为有了继承,才让面向对象的程序设计变得更加精妙。同时继承的功能也不仅仅是代码复用,更是多态的基础。
有下述3个定理决定了当java类型在继承是,生成子类时的步骤。
1)任何子类的构造方法一定会调用父类的构造方法;
2)任何类斗都有构造方法;
3)任何子类构造方法的第一行,一定是super()或者是this()这样的调用。
关于super和this的用法:
this:指本类对象
super:指父类对象
1)可以通过super.来访问父类的属性或方法,属性注意修饰符的作用范围;
2)子类中可以通过super.访问父类的构造方法,给属性赋值;
3)如果子类构造中没有对本类及父类的构造方法的调用,默认有super();
如果一个类没有指定继承其他父类,则它的父类是Object,对于一个对象来说,如果直接用syso输出该对象,是输出该对象的字符串形式,相当于默认调用对象.tosSring()
由于Object的toString()对我们没有意义,所以我们需要对String()方法进行重写,重写是注意重写规则。
多态:多态顾名思义,就是一个对象,多种形态,多态可以有多种理解,一种是方法的多态,即方法的覆盖和重载,这种多态提的比较少,一般讲的多态是指对象的多态:
*当把子类对象当做父类对象来看时,就只能调用父类中原有定义的属性和方法。子类自己扩展的属性和方法就不能调用了。
*当把子类对象当做父类对象看是,如果子类重写了父类中的方法,则调用该方法时调用的是子类重写后的方法。
下面一个例子解释一下上述的问题:
package blog; public class Pet { private String name; private int age; private String color; private double weight; public Pet() { super(); // TODO Auto-generated constructor stub } public Pet(String name, int age, String color, double weight) { super(); this.name = name; this.age = age; this.color = color; this.weight = weight; } @Override public String toString() { return "Pet [name=" + name + ", age=" + age + ", color=" + color + ", weight=" + weight + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public void eat(String food){ System.out.println(name+"喜欢吃"+food); } public void eat(int i){ System.out.println(name+"每天吃"+i+"顿饭"); } public void speak(){ System.out.println("MyPet likes Speaking!"); } }
子类继承父类代码如下:
package blog; public class MyDog extends Pet { public MyDog(String name,int age,String color,double weight) { super(name,age,color,weight); } public void speak(){ System.out.println(this.getName()+"说:旺旺,我是一只可爱的小狗狗!"); } public void watchHome(){ System.out.println(this.getName()+"还会看家哦!"); } }
测试方法:
package blog; public class TestMyDog { public static void main(String[] args) { Pet mydog = new MyDog("七仔",5,"灰色",0.25); if(mydog instanceof Pet){ mydog.eat("meat");//mydog可以调用Pet方法 mydog.speak();//mydog可以调用重写过的Pet方法 } // mydog。watchHome();//mydog不可以调用子类(自己)独有的方法,需要强转如下: ((MyDog)mydog).watchHome(); } }
输出结果如下:
七仔喜欢吃meat 七仔说:旺旺,我是一只可爱的小狗狗! 七仔还会看家哦!
其实封装继承多态是十分强大的,由于现在学的有限,希望以后会写出好的代码~^_^~