什么是面向对象?
面向对象编程(Object Oriented Programming,OOP,面向对象的程序设计)。所谓“对象”在显示支持面向对象的语言中,一般是指类在内存中装载的实例,具有相关的成员变量和成员函数(也称为:成员方法)。面向对象的程序设计完全不同于传统的面向过程程序设计,它大大降低了软件开发的难度,使编程就像搭积木一样简单。
什么是面向过程?
面向过程编程(Procedure Oriented Programming,OPP,面向过程的程序设计)。是一种以过程为中心的编程思想,这些都是在以什么正在发生为主要目标进行编程,不同于面向对象的是谁在受影响。与面向对象明显的不同就是封装、继承、类。
以上概念均参考自百度词条
面向对象三大特性:封装、继承、多态
这是由于OOP与OPP本质的区别,总结出来OOP特有的性状
1.封装
JAVA中的访问权限修饰符:public、private、protected、default(不加访问修饰符)。访问权限范围:
访问权限 | 类 | 包 | 子类 | 整个项目 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
这些访问修饰符,可以修饰类、属性、方法。
封装:通过private修饰符,可以将修饰的内容私有化,拒绝外部直接访问(这里的访问即调用的意思),从而将接口(这里不完全指interface接口,指的是方法、属性的调用)与实现(封装的部分)分离。
2.继承
提到继承就不得不说另一种方式----组合,这两张方式都是把一个类放到另一个类中。但是组合是显式的,继承是隐式的。
在继承中,子类相对于父类是is-a(是一个)的关系。通过继承可以使用向上转型来将父类转变为子类的类型。
在组合中,仅仅是将一个对象,放入到另一个类中作为该类的属性。是has-a(有一个)的关系。组合则不能使用向上转型。
向上转型?
在JAVA继承关系树中,父类总是在树的上方。所以子类转换成父类的过程称之为向上转型。
//创建Cat对象,自动向上转型 Animal animal1 = new Cat(); animal1.eat(); //创建Dog对象,自动向上转型 Animal animal2 = new Dog(); animal2.eat();
向上转型?
将父类转换成子类的过程称之为向下转型,此过程是不安全的
//将本身就是Animal类型的Dog对象,向下转型 Dog dog = (Dog)animal1; dog.eat(); //将本身不是Animal类型的Dog对象,向下转型-------失败ClassCastException Dog dog1 = (Dog)animal2; dog1.eat();
3.多态
多态:同一行为,产生不同的状态。
同一行为,指用“同一个类型”的对象调用“同样的方法”
不同状态,指产生了截然不同的结果
原因:动态绑定,本质原因是因为调用方法主体的不同。
什么是绑定?
* 将方法调用与方法主体的关联起来。
绑定分为前期绑定和后期绑定(动态绑定),对于static、final(private默认是final的)修饰的方法都是前期绑定,所以对这些方法的调用不存在多态。
多态的前提:方法的重载和重写,这样才能产生多个不同的方法主体,用于动态绑定。下面用例子来介绍:
先定义一个动物类:
package com.demo2;//动物接口public interface Animal { //动物进食 void eat();}
定义一个狗类,继承动物类:
package com.demo1;//狗类public class Dog extends Animal { @Override public void eat() { System.out.println("狗吃骨头。。。"); }}
定义一个猫类,继承动物类:
package com.demo1;//猫类public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼。。。"); }}
测试
package com.demo1;//测试类public class Demo { public static void main(String[] args) { Dog dog = new Dog(); Cat cat = new Cat(); dog.eat(); cat.eat(); System.out.println("多态的体现如下-------------------"); //直接new一个Animal对象 Animal animal = new Animal(); animal.eat(); //创建Cat对象,自动向上转型 Animal animal1 = new Cat(); animal1.eat(); //创建Dog对象,自动向上转型 Animal animal2 = new Dog(); animal2.eat(); }}
结果:
可以看出当直接new出Dog对象或者Cat对象时。调用eat时,都是调用了自身的重写的eat方法。
* 直接new出Animal对象,调用eat时,也是自身的eat方法。
* 但是当创建了Dog对象时,用自动的向上转型转换为父类Animal类型时,再次调用eat方法,调用的是Dog类中的eat方法。
同样都是Animal类型的对象调用eat方法(同一行为),
直接new出Animal时,输出的是Animal类中的内容,从Dog对象向上转型成的Animal时,则输出Dog类中的内容(不同状态),这就是多态。