6.1 this和super
-
this的三种用法
- this.域变量,this.成员方法:表示当前对象引用,常用于形参或局部变量与类的成员变量同名的情形
- 表示当前对象
- this(参数):调用当前类的构造方法
-
super的两种用法
- super.数据成员,super.成员方法:子类的数据成员或成员方法与父类的数据成员或成员方法名字相同时,当要调用父类的同名方法或同名数据成员时则可用super来指明
- super(参数):表示调用父类构造方法
6.2 构造方法的多态
子类对象实例化过程
- 为对象分配内存空间,对成员变量进行默认的初始化
- 绑定构造方法,将new中的参数传递给构造方法的形式参数
- 调用this或super语句(二者必居其一,不能同时存在)
- 进行实例变量的显式初始化操作
- 执行当前构造方法的方法体中的程序代码
注:成员方法中的变量如果不赋初值,则系统编译时会提示变量没有初始化,但类的域变量则不进行提示,原因在于类在生成对象时,可进行默认初始化。
6.3抽象类
- 抽象类中可以有零个或多个抽象方法,也可以包含非抽象方法。只要有一个抽象方法,类前就必须有abstract修饰。
- 抽象类必定要派生子类,若派生的子类是具体类,则具体子类中必须实现抽象类中定义的所有抽象方法(覆盖)
- abstract不能与final并列修饰同一个类(产生逻辑矛盾)abstract 不能与private ,static(因为static修饰的方法必然被直
接调用),final或native并列修饰同一个方法
6.4接口
- 接口定义的数据成员全是public final static(静态常量)。即使没有修饰符。
- 接口中没有构造方法;所有的抽象方法都是public abstract 方法(与抽象类有所不同)。
- 类在实现接口的抽象方法时,必须显式使用public修饰符
共同点:二者都可具有抽象方法,都不能实例化,但都可以有自己的声明,并能引用子类或实现类对象。
不同点:
6.5引用
- 父类引用可以指向子类对象,子类声明不能引用平行级别的其它类的对象,也不能引用父类对象
- 父类引用子类对象时,可以经过显式的转化赋给子类的声明,但子类的引用赋值给父类的声明则不需要。
- 引用比较
- equals方法是Object类的方法,比较本引用和参数指明的某个引用是否相等,即是否指向同一对象。
- 如果==”两边是对象引用则比较的是它们的引用是否相同;如果两边是数值,则比较的是它们的值(如果值类型不同,有可能发生类型转化,例如10==10.0将返回true);如果一边是引用,一边是值,则编译错误。
1、 如何实现两个对象之间互发消息,请举例说明。
将一个对象作为另一个对象的属性,且满足一下三个条件,即引用必须引用了特定的对象,对象必须定义了相应的属性或方法,被访问的属性或方法具有可访问的权限,则可以通过引用得到另一个对象的访问权,可以向另一个对象发送消息。
如下例,A中包括FighterPlane对象引用,利用该引用可以实现向FighterPlane对象发消息。
class FighterPlane
{
String name;
int missileNum;
public FighterPlane(String _name,int _missileNum){
name=_name;
missileNum = _missileNum;
}
public void fire(){
if(missileNum>0){
System.out.println("now fire a missile!");
missileNum-=1;
}else{
System.out.println("No missile left!");
}
}
}
class A
{
FighterPlane fp;
public A(FighterPlane fpp){
this.fp = fpp;//A中拥有了FighterPlane的对象引用
}
public void fireMissle(){
fp.fire();//A中对象发送消息给FighterPlane的对象
}
}
public class Run {
public static void main(String[] args)
{
FighterPlane ftp = new FighterPlane("su35",10);
A a = new A(ftp);
a.fireMissle();
}
}
2、谈谈组合与继承的区别以及两者的使用场景(即什么时候宜用组合?什么时候宜用继承?)。
组合使得对象之间的耦合性较为松散,在新类中创建原有类的对象,通过一个对象向另一个对象发送消息来进行关联。
继承则是子类继承父类的相应方法和属性,并可以添加新的功能。容易使得程序结构复杂化。
当各个部件之间没有关联时,只是简单的复用原有类中的方法,只需要使用组合就可以了,而若需要覆盖父类的方法,则需要用到继承。
3、Java中的运行时多态的含义是什么?有什么作用?请举例说明。
运行时多态:通过覆盖实现,Java运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果。
如下例,p.t()实际执行的是p引用的实例的t方法,究竟执行Dad类还是Child类的方法,运行时再确定。如果Child类声明了t()方法,则执行之;否则执行Dad类的t()方法。
class Dad{
public String t() {
String name = "dad";
return name;
}
}
class Child extends Dad{
public String t(){
String name = "child";
return name;
}
}
class Child2 extends Dad{
public String t(){
String name = "child2";
return name;
}
}
public class Test {
public static void main(String[] args) {
Dad p = new Child();
System.out.println(p.t());
p=new Child2();
System.out.println(p.t());
}
}
如下例,此时Dad类型要引用Child的实例,Dad没有定义t()方法,则需要显式将p转化为Child类。
class Dad{}
class Child extends Dad{
public String t(){
String name = "child";
return name;
}
}
public class test {
public static void main(String[] args) {
Dad p = new Child();
System.out.println(((Child)p).t());
}
}
4、 简述运算符instanceof的使用场景。
用法:boolean result = object instanceof class
判断对象是否为特定类的实例