一般问到面向对象有哪三种特征时?答: 封装 继承 多态
但被问到有哪四种特征时?答:抽象 封装 继承 多态
一,抽象
在Java语言中,用abstract关键字来修饰一个类时,这个类就叫做抽象类。
♦ 一般定义类型 - 是为了抽象某个实体的类型
♦ 基类类型 - 不是为了抽象某个实体的类型而定义的,它是为了
1.把派生类公共的成员抽取出来,放到基类里面,通过继承达到代码的复用
2.在基类里面给所有派生类保留统一的抽象方法,等待派生类重写,实现多态的使用
♦ 抽象类类型 - 用abstract关键字来修饰的类,要注意和普通类最大的区别是抽象类不能实例化对象。
抽象类:
1.抽象类中可以定义普通变量,static变量,final变量
2.抽象类可以定义实例方法,也可以定义抽象方法。(抽象方法没有方法体)
3.一个类只能继承一个抽象类。
4.一个类实现继承,表示的是一种is a的关系,说明这个类拥有基类定义的所有的方法。
抽象方法:
1.是在实例方法的返回值前面添加abstract,代表该方法不用提供实现
2.抽象方法一般放在基类里面
3.拥有抽象方法的类,一定得定义成抽象类
4.但抽象类 不一定拥有 抽象方法
5.抽象类里面提供的方法,所有的派生类必须都得支持
6.但是有些方法只有某些派生类支持,其它的派生类是不支持的,我们应该把这些方法定义在_接口has a_里面
7.派生类中一定要重写基类继承来的抽象方法
接口:
1.接口里面定义的变量默认就是public static final
2. 接口里面的方法不提供实现,默认是public abstract,但是 从jdk1.8以后,接口里面的方法也可以提供默认的实现,例:default void func();
3. 一个类可以实现多个接口
4.一个类实现接口,表示的是一种has a的关系,说明这个类拥有接口定义的功能方法
5.和继承抽象类的意义有本质的区别
代码实现:
1 package L13; 2 interface Animal2{ //定义接口 ,写的是某动物特有的功能 3 public static final int DATA=10; //定义的都为常量 4 public abstract void seeDoor(); //has not body 5 } 6 interface Animal3{ 7 public abstract void catchMouse(); 8 } 9 abstract class Animal1{ //定义一个抽象类 10 protected String name; //名字 11 public Animal1(String name){ 12 this.name=name; 13 } 14 15 public void eat(){ //每个动物都有吃的行为 16 System.out.println(" eating!!"); 17 } 18 public abstract void dark(); //定义一个抽象方法,等待派生类去重写。 19 } 20 class Dog extends Animal1 implements Animal2{ //Dog类中即包含了从基类继承下来的东西,还有自己定义的东西。 21 public Dog(){ //构造函数 22 super(" 狗"); 23 } 24 public void dark(){ //对于基类中的抽象方法,派生类继承后还必须进行重写。 25 System.out.println(name+"wang wang!!"); 26 } 27 public void seeDoor(){ 28 System.out.println("seedooring!!"); 29 } 30 31 } 32 class Cat extends Animal1 implements Animal3{ 33 public Cat(){ 34 super("猫"); 35 } 36 public void dark(){ 37 System.out.println(name+"miao miao!!"); 38 } 39 public void catchMouse(){ 40 System.out.println("catching the mouse!!"); 41 } 42 } 43 /*什么叫多态??? 44 * 多态就是用基类引用,引用不同的派生类对象,通过基类的引用变量调用同名覆盖 45 * 方法,这个基类引用引用了哪个派生类对象,就会调用哪个派生类对象重写的方法 46 * 47 * 它的好处就是,在代码设计的时候,不用给每一个派生类都提供相应的入口,而 48 * 是用基类引用接收所有的派生类对象,然后调用同名覆盖方法,实现多态调用 49 * 多态调用的实现(依赖函数的动态绑定实现的)*/ 50 class 多态{ 51 public static void show(Animal1 animal1){ //当new了一个猫传进来,编译时发现调用的dark()方法为实例方法,所以动态绑定 52 animal1.dark(); //然后通过引用animal1在堆上找到对象地址,根据地址末尾的方法表地址,找到该对象类型的方法表,发现在该对象类型的方法表中继承的Animal1类的
//dark()方法的地址已被该对象进行了重写,所以此时animal1.dark();掉用的方法就成对象重写之后的那个方法。
53 if(animal1 instanceof Animal2){ //判断若为接口Animal2的实例,则调用seeDoor()方法,此时还要将animal的类型强转为(Animal2)animal
54 ((Animal2) animal1).seeDoor(); //因为在编译阶段是用animal1调用seeDoor()方法,而Animal1类中没有seeDoor()方法,
55 } // 所以为了确保在‘编译阶段’不报错,只能将animal1转成 Animal2类,因为animall实现了Animal2接口,且Animal2接口中有seeDoor()方法。
56 if(animal1 instanceof Animal3){
57 ((Animal3) animal1).catchMouse(); 58 } 59 } 60 } 61 public class Animal { 62 public static void main(String[] args) { 63 /* Dog D=new Dog(); 64 D.name(); 65 D.eat(); 66 D.dark(); 67 Cat C=new Cat(); 68 C.name(); 69 C.eat(); 70 C.dark();*/ 71 多态.show(new Dog()); 72 多态.show(new Cat()); 73 74 } 75 }
运行过程:
二,封装与数据隐藏
封装:使用对象的方法将对象的变量与实现保护起来,对外进公开接口,外界只能通过对对象的接口访问对象的服务
从定义可知,对象中的数据封装也实现了对数据的隐藏。但是在系统中并非如此,对象可能需要暴露一些变量或隐藏它的
一些方法,而数据隐藏是通过对对象成员的访问权限进行控制实现的,即:public , protected , default/ 空白 , private。
三,继承
现实世界中,对象之间主要存在3种关系:组合 , 关联 ,继承。
组合:当对象A是对象B的成员变量,即满足 ...a part of...或....has a...时,称对象A和对象B为组合关系。
例如:发动机是汽车的一部分,则汽车和发动机就是组合的关系。
* class A{}
* class B{
* A a; // B组合了A对象
* public B{
* this.a = new A():
* }
* }
关联:当对象A中需要保存对象B的一个引用而不是对象B本身时,称对象A和对象B为关联关系。
继承:当对象A是对象B的一种,既满足...a kind of ..或...is a...时,称对象A和对象B为继承关系。
继承的意义:代码的复用。
继承的好处 :子类拥有父类的所有属性和方法(属性和方法的修饰符不能是private,不然是无效的)
注意:派生类的中继承的基类的方法,此方法的权限要大于等于基类中的。
例如:狗是动物的一种,则狗和动物为继承关系。
* class A{}
* class B extends A {
* }
四,多态
什么叫多态???
多态就是用基类引用,引用不同的派生类对象,通过基类的引用变量调用同名重写(覆盖)方法,这个基类引用引用了哪个派生类对象,就会调用哪个派生类对象重写的方法,它的好处就是,在代码设计的时候,不用给每一个派生类都提供相应的入口,而是用基类引用接收所有的派生类对象,然后调用同名覆盖方法,实现多态调用。
多态调用的实现(依赖函数的动态绑定实现的)
注: 一个类只能extends继承一个基类,但是可以implements实现多个接口