面向对象是继面向过程(以C语言为代表)的另一种以OOA(面向对象分析),OOD(面向对象设计),OOP(面向对象编程)的编程思想,它以更加符合人类的思维习惯和解决问题的方式,编写出更易维护,扩展性好的程序。
Java是完全支持面向对象的编程语言,支持面向对象的四个特征,抽象,封装,继承和多态,深入理解面向对象的诸多特性,才能合理使用设计模式构建可扩展和可维护的程序。
类是描述所有对象共同点(拥有相同的属性(field)和方法(method))的模板,同时类中还可以包含构造器和代码块,其中构造器主要用于实例化对象,完成对象自身的初始化操作,代码块主要也是在实例化对象之前完成一些初始化操作。方法中主要是定义业务逻辑实现,可以通过实例化对象完成对象方法的调用。开发人员要做的事就是定义类(也可以采用JDK中API),在类中根据业务需要完成属性、方法、构造器、代码块的定义和实现(调用)。
对象是类的实例(instance),对象可以通过调用构造器来创建对象。同时可以调用类中的(非静态)属性和方法来完成对应的业务逻辑。
package tony.javacore.object.oop.bean;
/** * 定义抽象父类Product * 抽取类产品的共有属性 id,name,price */
public abstract class Product {
/*私有化属性*/
private Long id; //产品编号
private String name; //产品名称
private Double price; //产品价格
/*提供公共的get set方法*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
/*重载的构造器*/
/** * 默认的构造器 */
public Product(){}
/** * 带参数的构造器 * @param id * @param name * @param price */
public Product(Long id, String name, Double price) {
this.id = id;
this.name = name;
this.price = price;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", price=" + price
+ "]";
}
/** * * @Description: <p>产品描述的抽象方法</p> * @return void * @throws * @date 2015年6月28日下午1:56:41 */
public abstract void description();
}
Product(产品)作为Memory(内存条)和MobilePhone(手机)的抽象父类抽取并封装了两个子类共有的属性(id,name,price),提供公共的get(获取属性值)和set(设置属性值)方法来访问属性。同时提供了重载(Overload)的构造器,用于实例化对象时赋值使用,以及完成对象的初始化动作。同时声明了一个抽象方法,用于描述产品,让MobilePhone和Memory去实现。
抽象方法只能包含在抽象类中(一个类中包含了抽象方法,那么这个类一定是个抽象类 ),使用abstract修饰。抽象类不能被实例化,不能采用new创建一个对象,抽象方法只声明,不实现(没有方法体)。
抽象父类Product的子类Memory
package tony.javacore.object.oop.bean;
import static tony.javacore.util.io.IOUtils.println;
/** * 定义抽象父类Product的子类Memory(内存) * @author tony [email protected] * @file Memory.java * @version 2016年2月6日下午6:14:54 * @since JDK7u80 */
public class Memory extends Product {
private int capacity; // 容量
/** * @return the capacity */
public int getCapacity() {
return capacity;
}
/** * @param capacity * the capacity to set */
public void setCapacity(int capacity) {
this.capacity = capacity;
}
/** * 默认的构造器 */
public Memory() {
super();
}
/** * 子类特有的构造器 * * @param capacity */
public Memory(int capacity) {
this.capacity = capacity;
}
/** * full args constructor * * @param id * @param name * @param price * @param capacity */
public Memory(Long id, String name, Double price, int capacity) {
super(id, name, price);
this.capacity = capacity;
}
@Override
public String toString() {
return "Disc [capacity=" + capacity + "]";
}
@Override // 实现父类的抽象方法
public void description() {
println("我是一条内存: id:" + super.getId() + "name :" + super.getName() + " price :" + super.getPrice() + "内存的容量为:"
+ this.getCapacity());
}
}
封装是指将隐藏实现细节,提供公共的访问方法。例如自定义类的成员变量,都是使用了私有化属性(private修饰符),提供公共(public修饰符)的访问方法来实现类的封装。
Java提供了四个访问权限修饰符来修饰类,成员变量和方法。分别是(权限从大到小)public protected default private四种。
public:全局范围类可以访问,用于修饰类,方法
protected:继承和包访问权限:用于修饰 方法
default:同包访问权限 ,用于修饰类,属性和方法
private:类访问权限,用于修饰属性,方法和内部类
package+packageName 表示存放于某个目录
import package+packageName+ClassName是用于导入某个包下的类
在项目开发过程中,经常会对PO(Persistant Object)持久化对象做封装处理,因为PO是对应数据库中的一条记录,而在业务处理中不太方便直接使用PO,一般会转换成BO(Business Object)后进行处理。
子类继承父类采用extends关键字实现,Java中的继承只能够支持单继承(只能有一个父类),所有的类默认(直接或者间接)都继承自java.lang.Object类。
子类必须实现抽象父类的抽象方法,除非子类也是一个抽象类。
自定义抽象父类Product的子类MobilePhone
package tony.javacore.object.oop.bean;
import static tony.javacore.util.io.IOUtils.println;
/** * * @description <p>定义抽象父类Product的子类MobilePhone(手机)</p> * @author Tony [email protected] * @porject_name Java * @package_name tony.javacore.oop.bean * @file_name MobilePhone.java * @see * @since JDK8.0 * @version 2015年6月28日 下午1:38:30 */public class MobilePhone extends Product {
/** * 私有化子类特有的属性 */
private boolean repleaceable; //是否可以更换电池
/*提供公共的get he set方法*/
/*重载的构造器*/
/** * @return the repleaceable */
public boolean isRepleaceable() {
return repleaceable;
}
/** * @param repleaceable the repleaceable to set */
public void setRepleaceable(boolean repleaceable) {
this.repleaceable = repleaceable;
}
/** * 定义子类MobilePhone的构造器 */
public MobilePhone(){
super(); //调用父类的无参数的构造器
}
/** * 生成子类特有的构造器 * @param rechargeable */
public MobilePhone(boolean repleaceable) {
this.repleaceable = repleaceable;
}
/** * 生成Battery的构造器 * @param id * @param name * @param price * @param rechargeable */
public MobilePhone(Long id, String name, Double price, boolean repleaceable) {
super(id, name, price);
this.repleaceable = repleaceable;
}
@Override
public String toString() {
return "MobilePhone [repleaceable=" + repleaceable + "]";
}
@Override //实现父类的抽象方法description
public void description() {
println("我是一只手机: id:"+super.getId() +"name :"+super.getName() +" price :"+super.getPrice()+"是否可以更换电池:"+this.repleaceable);
}
}
package tony.javacore.javacore.oop.test;
import org.junit.Test;
import tony.javacore.object.oop.bean.MobilePhone;
import tony.javacore.object.oop.bean.Product;
/** * * @description <p>OOP程序设计单元测试</p> * @author Tony [email protected] * @porject_name Java * @package_name tony.javacore.oop.bean * @file_name ProductHandlerTest.java * @see * @since JDK8.0 * @version 2015年6月28日 下午1:48:42 */
public class ProductHandlerTest {
@Test //实例化对象
public void testInstance() throws Exception {
//多态的表现:父类的引用指向子类的对象(编译时期和运行时期的类型不一样)
Product product =new MobilePhone();
product.setId(Long.valueOf(12)); //继承类父类就可以调用父类的属性和方法(在权限运行的情况下)
product.setName("iphone6s");
product.setPrice(Double.valueOf(100.00));
if(product instanceof MobilePhone){ //instanceof运算符用于判断对象的引用类型
MobilePhone mobilePhone =(MobilePhone) product;
mobilePhone.setRepleaceable(false);
}
product.description(); //这里调用的是子类的description方法,多态发生了
}
}