黑马程序员-Java的面向对象(抽象类、接口、内部类和继承、组合、多态)

时间:2022-10-01 00:48:25

                      -----------android培训、java培训、java学习型技术博客、期待与您交流!------------

                                              Java面向对象要点问题总结2 

1、继承:
  (1)提高代码的复用性;
  (2)使类与类之间产生关系,才可以产生OOP的多态特性。

   注:(1)不要为了其它类的功能,简化代码而去使没有所属关系的类
         之间继承。
    (2)先提取出每个对象,根据每个对象提取出抽象对象,接着实现
         父类和子类。

2、java只支持单重继承,不支持多重继承
   因为多重继承容易引起安全问题,当多个父类重定义了相同的方法,当子类调用方法时,不确定要运行哪一个。
   但利用多实现(多个接口)也可以实现类似C++中的多重继承的机制。

3、支持多层继承
   创建具体对象时,应该创建子类对象和父类的引用,因为
   (1)子类对象可以使用更多的方法;
   (2)可以实现多态的机制。
   注:查阅父类方法,创建子类对象。

4、聚集关系:某类中定义了其它类的对象
   聚合:两个类之间存在某种联系;
   组合:两个类之间存在某种更加紧密的联系。

5、继承中的变量
   子类和父类中有非私有的同名成员属性(几乎没有),当new一个子类对象时,
  (1)最后这个成员属性的值为子类中的;
  (2)通过this调用子类中的成员属性,它代表的是本类对象的引用;
  (3)通过super调用父类中的成员属性,它代表的是父类对象的引用;

   子类和父类中没有非私有的同名成员属性,当new一个子类对象时,
  (1)this和super调用的是同一个成员属性;

 
6、继承中的方法
  (1)覆盖(重写):当子类出现和父类一样的方法时,当子类调用该函数,
        只运行子类的方法,如同父类的方法被覆盖一样。
  (2)覆盖的使用:当子类继承父类的某个方法,但是子类的方法内容却和
        父类不一致时,采用覆盖特性,保留父类方法,重新定义子类方法的具体内容。
  (3)方法的扩展(建立在覆盖的基础上):采用super.方法()方式扩展。

   注:(1)子类覆盖父类,必须保证子类的权限大于等于父类权限,否则编译错误;
       (2)只有静态方法才能覆盖静态方法。
       (3)父类的方法是private时,子类中可以有相同的方法,但是不是覆盖,就不能
            实现多态;
       (4)重载只看同名方法的参数列表,而覆盖子父类方法名和参数列表要一模一样;
       当返回值和参数列表不一致时,编译无法通过。

7、继承中的构造方法
  (1)不管使用子类的任何构造方法,第一行都会默认隐式的语句调用super(),即父类的默认构造函数;
        如果要调用父类的其他构造方法,需要在第一行手动用super(x,...)显式的调用;
  (2)子类调用父类的构造函数的原因是父类中的数据子类可以继承获取,所以子类对象建立时,需要先
        查看父类中如何对这些数据进行初始化的。
   (3) 子类的一个构造函数中的第一行要么只有this语句,要么只有super语句;当第一行是this语句时,不会
        产生问题,因为子类中至少有一个构造函数会访问父类中的构造函数。


8、final关键字
  (1)可以修饰类、方法和属性;
  (2)被final修饰的类不可以被继承(因为继承打破了封装性,改变了类的方法,会造成一些问题);
  (3)被final修饰的方法不能被覆盖;处理类被final修饰时,所有方法都不能被覆盖的问题;
  (4)被final修饰的变量是一个常量,只能赋值一次,既可以修饰成员变量,也可以修饰局部变量;
       当在描述事物时,一些数据的出现值是固定的,为了增强阅读性,通过fianl修饰把这些值赋给
       一个变量,使其作为一个常量;这时通过static修饰使其可以被共享,当再加上public时,就
       编程了全局常量。
  (5)内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量;


9、抽象类
  (1)抽象方法一定在抽象类中;
  (2)抽象类中可以没有抽象方法,仅仅不让该类建立对象;
  (3)抽象方法和抽象类都必须被abstract关键字修饰;
  (4)抽象类不可以用new创建对象,因为调用抽象方法没有意义;
  (5)抽象类中的方法要被使用,必须由子类覆盖所有的抽象方法,才可以建立对象;
        如果子类只覆盖了部分抽象方法,那么盖子类还是一个抽象方法。
  (6)抽象类和一般类没有太大的区别,只不过,该事物中出现了一些抽象的东西;
        这些不确定的部分,也是该事物的功能,需要明确出现时,但是无法定义主体,
 通过抽象方法来表示。
  (7)与接口的使用的不同之处就在于它还可以定义一些可以共有的方法和成员变量,
        提高了代码的复用性。
  

10、接口:扩展一些特别的功能
    接口定义时的格式要求:
    (1)接口中常见定义:常量和抽象方法;
    (2)接口中的成员都有固定的修饰符;
         常量:public static final
  方法:pubic  abstract
         注:接口中的成员都是public的,如果没有写上面的修饰符,编译时会强制添加修饰符;
    (3)接口不能用来创建对象,因为所有的方法都是抽象的,需要被子类实现,子类对接口
  中的抽象方法全部覆盖后,子类才可以实例化,否则子类变成了一个抽象类。
    (4)用接口名可以直接调用接口中的常量;
    (5)接口可以被类多实现,也是对多继承不支持的变换形式(因为接口中的方法都是抽象的,
         所以重复的时候也不会有什么影响);
    (6)java支持继承一个类,同时实现多个接口;
    (7)接口之间也可以进行继承;要实现子类,继承的所有抽象方法都要覆盖;
         同时,接口支持一个接口继承多个接口,所以支持多继承。
         注:通过继承获得主体功能,通过接口获得扩展功能。


11、多态:一个对象具有多种形态,自始至终只有子类对象在发生变化
   (1)多态的体现:父类的引用指向(或接收)了自己的子类对象;
   (2)多态的前提:必须是类与类之间有关系,要么继承或者实现;
                    而且必须存在覆盖;
   (3)多态的好处:提高了程序的扩展性和复用性;
   (4)多态的弊端:提高了扩展性,但是只能使用父类的引用访问父类中存在的方法;
   (5)多态的应用:
 向上转型:自动的进行类型提升;为了调用共有的方法;
 向下转型:强制将父类的引用转成子类类型;为了调用特有的方法;
 注:(1)不要出现将父类对象强转为子类类型的操作;
     (2)向下转型的时候,需要采用instanceof判读类类型是否正确;

   (6)多态使用注意是事项:
        采用 父类  xxx  =  new 子类();形式,当调用xxx.方法()时:
        a、多态中非静态的方法的特点(动态绑定):编译看左边,运行看右边
    在编译时,检查引用型变量所属类中是否有被调用方法,如果没有,编译失败;
    在运行时,检查对象所属的类中是否有被调用的方法,如果没有,就使用它父类的方法。
       
 b、多态中静态方法的特点(静态绑定)
           无论编译还是运行,到检查左边(引用型变量所属的类)
 
 当调用xxx.变量 时:
 a、多态中成员变量(静态的和非静态的)的特点
    无论编译还是运行,到检查左边(引用型变量所属的类)


12、当new一个子类对象时,                    
   (1)先加载父类,然后加载子类;
   (2)当建立一个子类的对象时,先运行父类的构造方法和后运行子类的构造方法;
   (3)this和super都指向子类的对象;
   (4)父类的成员属性会在子类的对象中实例化;
       当有非私有的同名成员属性,同时存在两个同名成员属性,this和super分别指向;
       当没有非私有的同名成员属性时,子类中不存在一个成员属性,this和super都指向它;

   

class  Father{
int num = 4;
void show()
{
System.out.println("this.num= "+this.num);
}
}


class Child extends Father{
//int num = 5;
@Override
void show()
{
System.out.println("this.num= "+this.num);
System.out.println("super.num= "+super.num);
}

}

public class ExtendsDemo{
public static void main(String[] args){
System.out.println("-------------------父类--------------------");
Father father1 = new Father();
father1.show();
System.out.println(father1.num+","+father1.num);

System.out.println("-------------------子类继承--------------------");

Child child = new Child();
child.show();
System.out.println(child.num+","+child.num);

System.out.println("--------------------多态-------------------");

Father father2 = new Child();
father2.show();
System.out.println(father2.num+","+father2.num);
System.out.println("--------------------end-------------------");

}
}