您的位置:首页 > 职场人生

黑马程序员——Java面向对象(二)—继承、final、多态

2014-10-30 10:30 621 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------

一、继承

1、继承的概念:

就是对要描述的事物进行不断的向上抽取,就出现了体系结构。

要了解这个体系结构中最共性的内容,就看最顶层的类。

要使用这个体系的功能,就用最底层的类创建对象。

2、继承的好处:

A:继承的出现,提高了代码的复用性。

B:继承的出现,让类与类之间产生了关系,extends来表示,这个关系的出现,为后面我们讲面向对象的第三个特点多态打下了基础。

3、特点

A:java只支持单继承(其实确切的说是java对多继承进行了优化,避免了安全问题)。

B:java支持多重(层)继承。

4、注意:

A:子类可以直接访问父类中的非私有的属性和行为。

B:不要仅为了获取其他类中部分功能而去继承。

C:类与类之间要有所属( " is a " )关系,xx1是xx2的一种。

如何判断A和B是否有继承关系?

A如果继承B,那么就可以说A是B的一种。

5、继承后子父类之间成员的关系

(1)成员变量

class Fu{
int num = 5;
}

class Zi extends Fu{
int num = 20;

public void show() {
int num = 30;
System.out.println("num:"+num);
//当局部变量和成员变量重名的时候用this来区分
System.out.println("this num:"+this.num);
//当子类和父类出现了同名变量,用super来区分
System.out.println("father num:"+super.num);
}
}


总结:在一个类中如果方法中的局部变量和方法外的成员变量重名,那么如果在方法内输出这变量,就是方法自己的变量里的值,想要区分要用this,加上this.就是输出成员变量的值在子父类中如果出现成员变量重名的时候,在子类输出会输出自己的变量里的值,

想要区分要用super,加上super.就是输出父类里变量的值

this和super的区分:

this代表本类对象的引用

super本类对象父类的引用。

this可以用于区分局部变量和成员变量同名的情况。

super可以用于区分子类和父类成员变量同名的情况。

一般,子类中不会出现和父类同名的成员变量。(面试可能问到)

(2)成员方法

class Fu {
public void show() {
System.out.println("fu show");
}
public void method() {}
}

class Zi extends Fu{

public void show(){

System.out.println("zi show");
}
}
子类中存在和父类成员方法同名的这种现象,叫做重写,复写,覆盖。

重写(override)和重载(overload)的区别:

重载的特点:

在同一类中。

方法名相同,参数列表不同。

重写的特点:

要有继承关系。在子父类中

方法的声明相同。(方法名和参数列表都相同)

覆盖时,子类方法权限一定要大于等于父类方法权限

父类的权限不能是私有的

静态只能覆盖静态。

(3)构造方法

class Fu{

Fu(){}

Fu(int age){
System.out.println("father age:"+age);
}
}

class Zi extends Fu{
Zi(){
this(40);
System.out.println("son");
}

Zi(int age){
super();
System.out.println("son age:"+age);
}
}

Zi z = new Zi();

Zi z = new Zi(30);
总结:子类中所有的构造方法默认都会访问父类中空参数的构造方法。

因为每一个构造方法的第一行都有一条默认的语句super();

当父类中没有空参数的构造方法时,子类的构造函数必须通过this或者super语句指定要访问的构造方法。或者手动提供无参构造方法。

this(...):调用本类中的构造方法

super(...):调用父类中的构造方法

构造方法用于创建对象,并进行初始化.建议如果你写了有参的构造函数,也要把空参的构造函数再手动加上

否则你定义了有参的构造函数,空参的系统就不会再给了你这样创建对象的时候,

就会报错Person p = new Person();//这句话是会去找空参的构造函数

class Person{
Person(){}
Person(int age){
this.age = age;
}

Person(int age,String name){
this(age);
//this.age = age;
this.name = name;
}
}

//Person p =new Person();  //系统默认给出无参构造
//当你手动给出构造方法后,系统就不会再给出默认的空的构造方法。

class Demo{
private String name;
Demo(){}

public void setName(String name){
this.name = name;
}

public String getName(){
return name;
}
}
二、final

1、final可以用来修饰类:被fainl修饰的类不能被继承。

2、final可以用来修饰成员方法:被final修饰的成员方法不能被重写。

3、final可以用来修饰变量:被final修饰的变量为常量,值不能被修改。

常量的命名规范:要求大写。

final double X = 3.14;

final修饰的变量可以在声明的时候直接赋值,还可以在构造方法可以给final修饰的变量赋值。

三、多态

1、某一类事物的多种存在形态。

方法重载(静态多态)

方法重写(动态多态,对象多态)

2、对象多态的前提

A:类与类(或接口)要有继承(或实现)关系。

B:一定要有方法的重写。

C:一定要有父类或者接口的引用指向子类的对象。

3、多态中成员的调用

Fu f = new Zi();

A:成员变量

当子父中出现同名成员变量时,多态使用时,只看调用该成员变量的引用所属的类中的成员变量。

简单说:无论编译或者运行,都是等号左边

B:成员函数

当子父类出现一模一样函数时,多态调用,

编译时,看的是引用变量所属的类中的方法。

运行时,看的是对象的所述的类中的方法。

简单说,编译看左边,运行看右边。

C:静态函数:

当出现一模一样静态的函数时,多态调用,

编译和运行时,看引用变量所属的类中的方法。

简单说,变异和运行都看左边。

其实,真正调用静态方法是不需要对象的,直接类名调用。因此静态方法绑定到类上。

4、向上转型:

向上转型 Animal a = new Cat(); a.eat(); //a.catchMouse();

好处:隐藏了子类型,提高了代码的扩展性。

弊端:只能使用父类中的的功能,不能使用子类特有功能。功能被限定了。

什么时候用向上转型:

如果不需要面对子类型,通过提高扩展性,或者使用父类的功能即可完成操作,就是用向上转型。

5、向下转型:

Cat c = (Cat)a;
c.eat();
c.catchMouse();

//向上转型
Animal a = new Dog();
//向下转型 转换异常
//Cat c = (Cat)a;
Dog d = (Dog)a;
好处:可以使用子类型的特有功能,

弊端:面向具体的子类型。向下转型有风险。

只要转换类型和对象类型不匹配就会发生异常ClassCastException。想要安全,必须要进行判断。判断一个对象是否匹配某一个类型,需要使用一个关键字instanceof对象

if(!(a instanceof Dog))
{
system.out.println("类型不匹配");
}


总结:无论是向上转型还是向下转型,变化的都是子类对象,绝对不能把父类对象强转为子类类型

6、多态的好处和弊端

好处:提高了程序的扩展性

弊端:不能使用子类特有的属性和行为

-------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐