一、继承 继承用来解决成员变量或方法大量重复的问题, 将重复代码抽取到父类中 使用方法 //父类Apublic class A{ int a; //缺省(包权限),仅能在本包中使用 private int b; //私有,仅能在本
一、继承
继承用来解决成员变量或方法大量重复的问题, 将重复代码抽取到父类中使用方法
//父类A public class A{ int a; //缺省(包权限),仅能在本包中使用 private int b; //私有,仅能在本类中使用 public int c; //公有,在任何地方都可使用 protected int d; //保护类,缺省+不同包子类 public String toString(){...} } //假设有类B继承类A public class B extends A{ int a; //变量的隐藏 public String toString(){...} //方法的重载(重写) }1
//父类A
2
public class A{
3
int a; //缺省(包权限),仅能在本包中使用
4
private int b; //私有,仅能在本类中使用
5
public int c; //公有,在任何地方都可使用
6
protected int d; //保护类,缺省+不同包子类
7
8
public String toString(){...}
9
}
10
11
//假设有类B继承类A
12
public class B extends A{
13
int a; //变量的隐藏
14
public String toString(){...} //方法的重载(重写)
15
}
//编译器会一直上溯到最顶端的超类,执行该类构造方法,然后依次执行各子类构造函数 class A{ public A(){ System.out.println("调用了A类的构造方法"); } } class B extends A{ public B(){ System.out.println("调用了B类的构造方法"); } } public class C extends B { public C(){ System.out.println("调用了C类的构造方法"); } public static void main(String args[]) { C c=new C(); } } /* 程序运行结果: 调用了A类的构造方法 调用了B类的构造方法 调用了C类的构造方法 /*
x1
//编译器会一直上溯到最顶端的超类,执行该类构造方法,然后依次执行各子类构造函数
2
3
class A{
4
public A(){
5
System.out.println("调用了A类的构造方法");
6
}
7
}
8
class B extends A{
9
public B(){
10
System.out.println("调用了B类的构造方法");
11
}
12
}
13
public class C extends B {
14
public C(){
15
System.out.println("调用了C类的构造方法");
16
}
17
18
public static void main(String args[]) {
19
C c=new C();
20
}
21
}
22
23
/*
24
程序运行结果:
25
调用了A类的构造方法
26
调用了B类的构造方法
27
调用了C类的构造方法
28
/*
super关键字(重点)
表示对子类对父类的鹰用 如果在子类中未显式调用父类构造方法,则编译器会默认 使用super()自动调用父类的无参构造方法(默认/覆盖),假若父类没有提供无参构造方法,编译时将出错//引用父类的成员(需要相应的访问权限): super.变量 super.方法([参数表]) //在子类构造方法中调用父类的构造方法: super([参数表]); //必须放在构造方法的第一行位置上6 1
//引用父类的成员(需要相应的访问权限):
2
super.变量
3
super.方法([参数表])
4
5
//在子类构造方法中调用父类的构造方法:
6
super([参数表]); //必须放在构造方法的第一行位置上
instanceof运算符
用于判断一个类是否实现接口或判断一个对象是否属于一个类//instanceof运算符格式 对象 instanceof 类或接口 //结果:true或false
x1
//instanceof运算符格式
2
对象 instanceof 类或接口
3
//结果:true或false
使用注意事项
- 子类并不能继承父类的所有变量或方法,需要看父类成员的访问权限
二、多态
同一个引用类型,使用不同的示例而执行不同的结果对象的类型转换
//子类转父类:向上转型 子类对象句柄 = (子类名) 父类对象;//需要强制转换,损失精度 //父类转子类:向下转型 父类对象句柄 = 子类对象;5 5 1
//子类转父类:向上转型
2
子类对象句柄 = (子类名) 父类对象;//需要强制转换,损失精度
3
4
//父类转子类:向下转型
5
父类对象句柄 = 子类对象;
1、静态多态(编译时多态)
静态多态主要是指 方法重载, 与是否发生与继承没有必然联系2、动态多态(运行时多态)
条件
- 必须要有继承的情况存在
- 在子类中重写父类的方法
- 必须由父类的引用指向派生类的实例,并且通过父类的引用调用重写的方法。(向上转型)
使用举例
//多态性的例子(续) public class AnimalTest { public static void main(String args[]){ Animal am=new Animal(); am.roar(); am=new Dog(); am.roar(); am=new Cat(); am.roar(); } } /*程序运行结果: 动物:... 狗:汪,汪,汪,... 猫:喵,喵,喵,...*/12 1
//多态性的例子(续)
2
public class AnimalTest {
3
public static void main(String args[]){
4
Animal am=new Animal();
5
am.roar();
6
am=new Dog();
7
am.roar();
8
am=new Cat();
9
am.roar();
10
}
11
}
12
/*程序运行结果:
13
动物:...
14
狗:汪,汪,汪,...
15
猫:喵,喵,喵,...*/
根据对象的赋值规则,可以把子类对象赋给父类对象名
父类对象名.roar()去调用时,能够根据子类对象的不同,得到不同的结果,这就是多态性。
三、抽象
抽象类指不能实例化的类,其可以包含或不包含抽象方法抽象类生来就是为了被子类继承
抽象类与具体类的比较
抽象类 具体类 用于划分具体类 用于表示真实世界的对象 不能实例化 可以实例化 可定义未提供实现的抽象方法 不能定义未提供实现的抽象方法 可为自己的部分方法提供实现 为所有方法提供实现使用方法
//抽象类的定义格式: [访问权限] abstract class 类名{……} //如 abstract class Shape {……} //抽象方法的定义格式: [访问权限] abstract 返回类型 方法名([参数表]);//无方法体 //抽象方法举例: public abstract double getArea(); public abstract double getPerimeter();10 1
//抽象类的定义格式:
2
[访问权限] abstract class 类名{……}
3
//如
4
abstract class Shape {……}
5
6
//抽象方法的定义格式:
7
[访问权限] abstract 返回类型 方法名([参数表]);//无方法体
8
//抽象方法举例:
9
public abstract double getArea();
10
public abstract double getPerimeter();
使用注意事项(重点)
- 当一个类中包含有抽象方法时,该类一定要声明为抽象类
- 子类继承抽象类时,必须实现该抽象类中的所有抽象方法
- 当类实现了一个接口,但并没有实现该接口的所有方法时,该类必须声明为抽象类,否则出错
- 抽象方法无方法体,在缺省情况下默认为public
- 抽象方法不能被private、final或static修饰
- 抽象方法必须被子类所覆盖,所以不能用final修饰;如果说明为private,则外部无法访问,覆盖也无从谈起;若说明为static,即不创建对象也能访问:类名.方法名() ,这要求给出方法体,但与抽象方法的定义相矛盾。
四、接口
接口可以实现不相关类的相同行为,
只关注功能,不关注具体实现
一个类可以继承多个接口
接口中的方法都是抽象方法,成员变量都为静态常量
使用方法
//接口的定义——interface关键字 [权限修饰符] interface 接口名 [extends 父接口列表]{ //抽象方法和静态常量 } //如 public interface Runner { int id = 1; public void start();//无方法体 public void run(); public void stop(); } //接口的实现——implements关键字 [修饰符] class 类名 [extends 父类] implements 接口1[,接口2,…]{ …… //包含对接口的所有方法的实现 } //接口实现示例 public class Person implements Runner{ public void start() { // 准备工作:弯腰、蹬腿、咬牙、瞪眼 // 开跑 } } //接口的继承——允许一个接口用extends继承另一个接口 接口名 extends 父接口1[,父接口2,…]{ …… //新增的抽象方法或静态常量 }28 1
//接口的定义——interface关键字
2
[权限修饰符] interface 接口名 [extends 父接口列表]{
3
//抽象方法和静态常量
4
}
5
//如
6
public interface Runner {
7
int id = 1;
8
public void start();//无方法体
9
public void run();
10
public void stop();
11
}
12
13
//接口的实现——implements关键字
14
[修饰符] class 类名 [extends 父类] implements 接口1[,接口2,…]{
15
…… //包含对接口的所有方法的实现
16
}
17
//接口实现示例
18
public class Person implements Runner{
19
public void start() {
20
// 准备工作:弯腰、蹬腿、咬牙、瞪眼
21
// 开跑
22
}
23
}
24
25
//接口的继承——允许一个接口用extends继承另一个接口
26
接口名 extends 父接口1[,父接口2,…]{
27
…… //新增的抽象方法或静态常量
28
}
使用注意事项
- 接口中的所有方法都是抽象的,只有声明、没有方法体
- 接口不可以被实例化,常作为类型使用
- 实现类必须实现接口的所有方法
- 接口中的常量默认是公共的、静态的和最终的,在声明时一般不需要用public、static、final。
来自为知笔记(Wiz)