Java中的继承与多态

1、为什么要有继承性

2、通过 "class A extends B" 类实现类的继承。

  * 子类:A 父类(或基类 SuperClass):B
  * 子类继承父类以后,父类中声明的属性、方法,子类就可以获取到。
  *         说明: 当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接调用罢了。
  * 子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分。
  *
  * extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。
  *
4、java中类的继承性只支持单继承:一个类只能继承一个父类。反之,一个父类可以有多个子类。子父类是相对的概念。

5、方法的重写(override orverwrite) vs 重载(overload)

  【面试题】方法的重载与重写的区别?
  重载: 同一个类,同一个方法名,不同的参数列表。 注:方法的重载与方法的返回值无关!
      >构造器是可以重载的
  重写:(前提:在继承的基础之上,子类在获取了父类的结构以后,可以对父类中同名的方法进行“重构”)
    方法的返回值,方法名,形参列表形同;权限修饰符不小于父类的同名方法;子类方法的异常类型不大于父类的;
    两个方法要同为static或同为非static。

6、super,相较于关键字this,可以修饰属性、方法、构造器

  1)super修饰属性、方法:在子类的方法、构造器中,通过super.属性或者super.方法的形式,显式的调用父类的指定
属性或方法。尤其是,当子类与父类有同名的属性、或方法时,调用父类中的结构的话,一定要用“super.”

  2)通过“super(形参列表)”,显式的在子类的构造器中,调用父类指定的构造器!

    >任何一个类(除Object类)的构造器的首行,要么显式的调用本类中重载的其它的构造器“this(形参列表)”或显式的调用父类中指定的构造器“super(形参列表)”,要么默认的调用父类空参的构造器"super( )"

    >建议在设计类时,提供一个空参的构造器!

7、多态性的表现:①方法的重载与重写   ②子类对象的多态性

  * 使用的前提:①要有继承关系 ②要有方法的重写
  * 格式:Person p1 = new Man( ) ;  //向上转型
  * 虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法

  p1.eat();
  p1.walk();
  重点说明:  父类Person类中有eat( )方法,子类Man类中有重写的eat( )方法、walk( )方法
           p1调用的eat( )方法是父类Person的还是Man的?调用walk( )能运行么?
    >编译时,认为p1是Person类型的,故只能执行Person里才有的结构,即Man里特有的结构不能够调用子类对象的多态性,并不使用于属性。

8、关于向下转型
  ①向下转型,使用强转符:(  )
  ②为了保证不报ClassCastException,最好在向下转型前,进行判断: instanceof
  // 若a是A类的实例,那么a也一定是A类的父类的实例。
  if (p1 instanceof Woman) {
    System.out.println("hello!");
    Woman w1 = (Woman) p1;
    w1.shopping();
  }

9、java.lang.Object 类,是所有类的根父类!

  * Object类仅有一个空参的构造器 public Object(){ }
  * 关于方法:
  ① equals(Object obj)

  public boolean equals(Object obj) {
    return (this == obj);
  }
  // ==
  // 1.基本数据类型:根据基本数据类型的值判断是否相等。相等返回true,反之返回false
  //                     注:两端数据类型可以不同,在不同的情况下,也可以返回true。
  // 2.引用数据类型:比较引用类型变量的地址值是否相等。
  // equals( ):
    >①只能处理引用类型变量②在Object类,发现equals()仍然比较的两个引用变量的地址值是否相等
    >像String 包装类 File类 、Date类这些重写Object类的equals()方法,比较是两个对象的"实体内容"是否完全相同。
    >若我们自定义一个类,希望比较两个对象的属性值都相同的情况下返回true的话,就需要重写Object类的equals(Object obj)方法

  ② toString()方法
  当我们输出一个对象的引用时,会调用toString()方法。
  public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
  }
  当我们没有重写Object类的toString()方法时,打印的就是对象所在的类,以及对象实体在堆空间的位置

  【说明】像String类、Date、File类、包装类都重写了toString()方法。

10、包装类

  基本数据类型由于不是类,不能够使用java类库里提供的大量的方法。所有在设计上,我们让每一个基本数据类型都对应一个类,同时数据存储的范围还不变。此时相当于基本数据类型就具有了类的特点。这些类即为包装类(wrapper 或封装类)

  重点:  1)掌握基本数据类型的包装类,及其包装类中的属性和方法;

       2)基本数据类型与String类型的转换。
          基本数据类型---->String类:  调用String类的重载的valueOf(Xxx xx);
          String类---->基本数据类型:  调用相应的包装的parseXxx(String str);

11、final

  /*
  * final:最终的 ,可以用来修饰类、属性、方法
  *
  * 1.final修饰类:这个类就不能被继承。如:String类、StringBuffer类、System类
  *
  * 2.final修饰方法:不能被重写。如:Object类的getClass()
  *
  * 3.final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。
  * 此常量在哪里赋值:①此常量不能使用默认初始化 ②可以显式的赋值、代码块、构造器。
  *
  * 变量用static final修饰:全局常量。比如:Math 类的PI
  *
  * >与finally finalize()区分开
  *
  */

12、【重点】抽象类与抽象方法

  abstract:抽象的,可以用来修饰类、方法

  * 1.abstract修饰类:抽象类
  * 1)不可被实例化
  * 2)抽象类有构造器 (凡是类都有构造器)
  * 3)抽象方法所在的类,一定是抽象类。
  * 4)抽象类中可以没有抽象方法。
  * >当我们设计一个类,不需要创建此类的实例时候,就可以考虑将其设置为抽象的,由其子类实现这个类的抽象方法以后,就行实例化
  *
  * 2.abstract修饰方法:抽象方法
  * 1)格式:没有方法体,包括{}.如:public abstract void eat();
  * 2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。
  * 3)若子类继承抽象类,并重写了所有的抽象方法,则此类是一个"实体类",即可以实例化
  * 4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的!

13、接口(interface) 

  * 1.接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。
  * 2.接口是没有构造器的。
  * 3.接口定义的就是一种功能。此功能可以被类所实现(implements)。 比如:class CC extends DD implements AA
  * 4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写所有的抽象方法,则此类仍为一个抽象类
  * 5.类可以实现多个接口。----java 中的类的继承是单继承的
  * 6.接口与接口之间也是继承的关系,而且可以实现多继承
  * >5,6描述的是java中的继承的特点。
  * 7.接口与具体的实现类之间也存在多态性

14、内部类

  * 1.相当于说,我们可以在类的内部再定义类。外面的类:外部类。里面定义的类:内部类
  * 2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里)
  * 3.成员内部类:
  *   3.1是外部类的一个成员:①可以有修饰符(4个)②static final ③可以调用外部类的属性、方法
  *
  *    3.2具体类的特点:①abstract ②还可以在其内部定义属性、方法、构造器
  *
  * 4.局部内部类:
  *
  * 5.关于内部类,大家掌握三点:
  *    ①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象)
  *    ②如何区分调用外部类、内部类的变量(尤其是变量重名时)
  *    ③局部内部类的使用 (见TestInnerClass1.java)

【补充】工厂方法的设计模式

//接口的应用:工厂方法的设计模式
public class TestFactoryMethod {
public static void main(String[] args) {
IWorkFactory i = new StudentWorkFactory();
i.getWork().doWork();

IWorkFactory i1 = new TeacherWorkFactory();
i1.getWork().doWork();
}
}

interface IWorkFactory{
Work getWork();
}
class StudentWorkFactory implements IWorkFactory{

@Override
public Work getWork() {
return new StudentWork();
}

}
class TeacherWorkFactory implements IWorkFactory{

@Override
public Work getWork() {
return new TeacherWork();
}

}

interface Work{
void doWork();
}

class StudentWork implements Work{

@Override
public void doWork() {
System.out.println("学生写作业");
}

}
class TeacherWork implements Work{

@Override
public void doWork() {
System.out.println("老师批改作业");
}

}

posted @ 2018-10-01 13:38  imanuu  阅读(5)  评论(0)    收藏  举报