类的继承性
类的继承性表现为子类继承父类相关的数据成员和成员方法。
类的多态性
多态是指同名的不同方法根据发送消息的对象以及方法传送参数的不同,采取不同的行为方式的特性。
“一个接口,多种方法”
Java中提供两种多态机制:覆盖个重载
一、覆盖和重载
方法的覆盖和重载时Java多态性的不同表现。
覆盖也可叫做重写,是父类与子类之间多态性的一种表现。(子类重新定义父类)
重载是一个类中多态性的一种表现。(同一类中定义多个构造方法)
1. 方法的覆盖
如果在子类中定义某方法与其父类有相同的名称和参数,则该方法覆盖(重写)父类中的方法。
例:override.java
class A{
public int getval() {
return(5);
}
}
class B extends A{
public int getval() {
return(10);
}
}
public class override {
public static void main(String args[]) {
B b=new B();
System.out.println(b.getval());
}
}
运行结果:
10
- 上转型对象
1)上转型对象不能操作子类新增的成员变量和子类新增的方法。
2)上转型对象可以操作子类继承或重写的成员变量,也可以使用子类继承或重写的方法。
3)如果子类重写了父类某个方法后,当对象的上转型对象调用这个方法一定是调用了这个重写的方法。 - 覆盖方法的调用原则:
1)父类被覆盖的方法的声明必要和子类的同名方法的声明完全匹配,才能达到覆盖的效果。
2)覆盖的方法的返回值必须和被覆盖的方法的返回值一致。
3)被覆盖的方法不能private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖,因为修饰符为private的方法,子类不能从父类继承,所以覆盖也不存在了。
4)当Java程序运行时,系统根据调用该方法的对象,来决定实际调用的是子类还是父类的方法。
5)重写后的方法不能比被重写的方法有更严格的访问权限(可以相同)。
6)重写后的方法不能比重写的方法产生更多的例外,即抛出更多的异常。
例:
class A{
void f() throws IOException{//f()为default类型,抛出IOException
//方法体
}
}
class B extends A{
private void f() throws Exception{ //此处有两个错误
//一是private权限小于default,二是Exception异常比IOException
//异常范围大,因为Exception包含IOException
}
}
2. 方法的重载
如果一个类中定义了多个同名的方法,它们或有不同的参数个数,或有不同的参数类型,或有不同的参数次序,则称为方法的重载。
3. 覆盖与重载的区别
1)方法的覆盖是子类和父类之间的关系,重载是同一类内部多个方法间的关系。
2)方法的覆盖一般是两个方法的覆盖,重载时可能有多个重载方法。
3)覆盖的方法有相同的方法名和形参表,重载的方法只能有相同的方法名,不能有相同的形参表。
4)覆盖是区分方法的是根据调用它的对象,而重载是根据形参来决定调用的是哪个方法。
5)用final修饰的方法是不能被子类覆盖的,只能被重载。
二、运行时多态
多态分为两种:编译时多态,运行时多态
1.通过继承父类对象的引用变量来引用子类对象的方法来实现
例:test.java
class superA{
void fun() {
System.out.println("this is superA");
}
}
class subB extends superA{
void fun() {
System.out.println("this is subB");
}
}
class subC extends superA{
void fun() {
System.out.println("this is subC");
}
}
public class test {
public static void main(String args[]) {
superA a; //声明a属于superA
subB b=new subB();
subC c=new subC();
a=b;
a.fun();
a=c;
a.fun();
}
}
运行结果:
this is subB
this is subC
2. 通过接口类型变量引用实现接口的类的对象来实现
例:test2.java
interface InterA{
void fun();
}
class b implements InterA{
public void fun() {
System.out.println("this is b");
}
}
class c implements InterA{
public void fun() {
System.out.println("this is c");
}
}
public class test2 {
public static void main(String args[]) {
InterA a;
a=new b();
a.fun();
a=new c();
a.fun();
}
}
静态修饰符、静态数据成员、静态成员方法
一、静态修饰符
static称为静态修饰符,可以修饰类中的数据成员和成员方法,有些面向对象语言使用了类数据成员和类方法这两个术语。
要将数据成员或成员方法设为static,只需要在定义时设置这个关键字即可。
二、静态数据成员
三、静态常量
用关键字static修饰的常量为类常量;没有关键字修饰的常量为实例常量。为提高效率,应当创建常量,或者说是final static字段。
静态成员方法
static修饰符修饰的属性是类的公共属性。
在静态方法中不能调用非静态的方法和引用非静态的成员变量,反之则可以。
抽象类和最终类
一、抽象类
当一个类被声明为abstract时,这个类就是抽象类,抽象类就是没有具体实例对象的类。
abstract是抽象修饰符,可以用来修饰类和方法。
抽象类需注意规则:
1)抽象类不能直接实例化,并且对抽象类使用new运算符是编译时错误。
2)抽象类的数据成员和成员方法都是其子类的公共数据成员和方法的集合。
3)抽象类中既存在抽象方法,也存在一般方法。
4)对于父类中的抽象方法是通过子类覆盖父类抽象方法的形式来实现继承的,子类必须实现父类的所有抽象方法,否则该子类必须仍然定义为抽象类。即如果定义一个具体子类继承于某个抽象父类,那么该子类必须实现抽象父类中的抽象方法。
5)抽象类不能被密封(注意abstract修饰方法时不能和static、final、native、private一起使用)。
例: employee.java
abstract class printmechine{
abstract public void print(int x);
}
public class employee extends printmechine{
int a;
public employee(int a) {
this.a=a;
}
public void print(int a) {
System.out.println(a*2);
}
public static void main(String args[]) {
printmechine p=new employee(3);
p.print(3);
}
}
二、最终类
如果用final修饰成员变量,会使改变量成为常量。如果用来修饰成员方法,表示该方法无法在子类中被覆盖。