面向对象的编程4
super关键字
1.super()
super():只能出现在构造方法的第一行,通过当前的构造方法去调用父类的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
注意:当一个构造方法第一行既没有this()又没有super()会默认有一个super(), 默认去调用父类的无参构造方法,所以最好保证父类有无参的构造方法。
栗子
public class supertext1
{
public static void main (String[] args){
new b();
}
}
class a
{
public a(int i ){
System.out.println("a类的有参数构造方法");
}
public a (){
System.out.println("a类的无参数构造方法");
}
}
class b extends a
{
public b(){
//当第一行没有东西时,会自动加一个super()
System.out.println("b类的无参数构造方法");
}
输出结果:
a类的无参数构造方法
b类的无参数构造方法
2.super.
与this.相近,super.表示访问父类型对象的属性,大多数情况下也可以省略,下面我们来看一下什么时候不可以省略
栗子1
public class supertext2
{
public static void main (String[] args){
vip v = new vip ("张三");
v.shopping();
}
}
class customer
{
String name;
public customer (){}
public customer (String name){
this.name = name;
}
}
class vip extends customer
{
//java中允许子类和父类有同名属性
//假设子类也有一个同名属性
//super表示父类型的特征
String name;
public vip (){}
public vip (String name){
super(name);
//this.name = null;没有对this.name进行赋值,所以系统默认赋值初始值
}
public void shopping(){
//此时若要访问父类型变量,super就不能省略
System.out.println(this.name+"正在购物");
System.out.println(super.name+"正在购物");
//这个name默认是this.name
System.out.println(name+"正在购物");
}
}
输出结果:
null正在购物
张三正在购物
null正在购物
栗子2
public class supertext3
{
public static void main (String[] args){
cat c = new cat();
c.yiDong();
}
}
class animal
{
public void move (){
System.out.println("animal move");
}
}
class cat extends animal
{
public void move (){
System.out.println("猫在走猫步");
}
public void yiDong(){
this.move();
//这个move默认是this.move()
move();
super.move();
}
}
输出结果:
猫在走猫步
猫在走猫步
animal move
多态
1.向上转型与向下转型
我们需要先普及两个概念:
一:向上转型:子–>父(自动类型转换)
二:向下转型:父–>子(强制类型转换,要加强转转换符)
什么时候需要向下转型:
需要调用子类特有的方法时
2.instanceof运算符
这个运算符可以在运行阶段动态判断指向的对象的类型
语法:(对象名 instanceof 类型)
若所判断的对象名是后面的类型,返回true,否则返回false
3.多态的基础语法
animal类
public class animal
{
public void move (){
System.out.println("动物在移动");
}
}
brid类
public class brid extends animal
{
public void move (){
System.out.println("鸟儿在飞翔");
}
}
cat类
public class cat extends animal
{
public void move (){
System.out.println("猫在走猫步");
}
public void catMouse(){
System.out.println("猫在抓老鼠");
}
}
text
public class text
{
public static void main (String[] args){
animal a1 = new animal();
cat c1 = new cat();
brid b1 = new brid();
a1.move();
b1.move();
c1.move();
animal a2 = new cat ();
animal a3 = new brid();
//经过测试,java中父类型的引用允许指向子类型的对象
//调用a2,a3的move
a2.move();//猫在走猫步
a3.move();//鸟儿在飞翔
//什么是多态:多种形态 多种状态
//java程序分为编译和运行阶段
//在编译时,编译器只知道a2,a3的类型是animal,所以
//比编译器会去animal中找move方法,找到后绑定成功
//运行时,实际上在堆内存中创建的是cat和brid对象,真正
//参与的move的对象是猫和鸟,所以在运行时会执行cat和brid
//的move方法,属于运行阶段绑定
//这就是多态:编译时一种形态,运行时另一种形态
animal a5 = new cat();
a5.catMouse();//编译错误,因为编译器只知道a5的类似是animal,所以去animal中找move,但并没有
//若一定要调用catMouse方法
//这个时候必须使用向下转型(强制类型转换)
cat x = (cat)a5;
x.catMouse();//猫在抓老鼠
//向下转型有风险吗?
animal a6 = new brid();
cat y = (cat)a6;
y.catMouse();
//编译通过但是运行报错,运行阶段,堆内存实际创建的是
//一个brid对象,在运行中,吧brid转成cat不行,二者没有继承关系
//java.lang.ClassCastException类型转换异常
//怎么避免呢?instanceof运算符
System.out.println((a6 instanceof cat));
//如果是猫这个类型再向下转型
if ((a6 instanceof cat))
{
cat z = (cat)a6;
z.catMouse();
}
//好习惯:在向下转型时一定要instanceof
}
}