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

黑马程序员---多态

2015-06-20 02:33 609 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

第一讲 多态

一,多态

1.父类的引用指向它的某个子类的对象。这种形式就叫:多态

2.多态的前提和体现:

1).前提:一定要有继承关系;

要有方法的重写;

用父类的引用指向子类的对象

class Animal
{
}
class Cat extends Animal
{

}
class Dog extends Animal
{
}
class Employee
{
}
class Demo
{
public static void main(String[] args)
{
//正常情况下,实例化一个Cat对象
Cat c = new Cat();
//使用多态,父类的引用指向子类的对象
Animal a = new Cat();//OK的
Animal a2 = new Dog();//OK的

Animal a3 = new Employee();//编译错误。多态必须要有继承关系;
}
}
二,多态中成员的访问特点

1.多态时,通过父类的引用访问的必须是父类中定义的,不能访问子类特有的成员;

二.发生覆盖时:

1.普通成员变量:编译看左边:编译时,父类中必须要有此成员,否则编译错误

运行看左边:运行后,打印的,也是父类的内容;

2.普通成员方法:

编译看左边: 编译时,父类中必须要有此成员,否则编译错误

运行看右边:运行时,运行时的是"子类中的方法"

3.静态成员方法:静态的,跟"类"有关,跟"对象"无关,不存在动态绑定:

编译看左边:编译时,父类中必须要有此成员,否则编译错误

运行看左边:运行后,打印的,也是父类的内容;

总结一句话:多态时,访问的成员,父类中必须要有;只有成员方法是调用的子类的,其它都是父类的

三,多态好处与弊端

好处:提高了程序的维护性(由继承保证)

弊端:多态时,不能访问子类特有的成员

class A
{

}
class B extends A
{
void show(){
System.out.println("B --> show()");
}
}

class Demo
{
public static void main(String[] args)
{
A a = new B();
a.show();//编译错误,不能访问子类特有的成员;
}
三,多态的类型转换

1.向上转型:父类的引用指向了子类对象。隐式的自动转换

class A{}

class B extends A{}

main(){

A a = new B();//向上转型

}

特点:

1.多态;

2.访问的只能是父类中定义的成员,不能访问子类特有的成员;

2.向下转型:如果确定父类类型指向了某个子类的对象,那么可以将这个父类型的引用

强制转换为它所指向的子类类型的引用。

注意:向下转型时,由于有可能会发生ClassCastException。所以,为了安全起见,Java为我们提供了一个

判断的运算符:instanceof

1.双目运算符:

2.使用格式:变量 instanceof 某个类类型

3.它会返回一个boolean值,如果"变量"是"某个类类型",那么返回true,否则返回false;

4.在强制转换前,可以使用这个操作符进行判断;

class A
{
void show(){
System.out.println("A-->show()");
}
}
class B extends A
{
void method(){
System.out.println("B-->method()");
}
}
class C extends A
{

}
class Demo
{
public static void main(String[] args)
{
A a = new B();//隐式的,向上转型
a.show();
///	a.method();//不可以,编译错误,不能访问子类特有成员;

//可以将变量a强制转换为B类类型;
B b = (B)a;
//转换后,就可以访问子类特有的成员了
b.method();

//	C c = (C)a;//不可以。B和C没有关系,不能强制转换。编译可以通过,运行时异常:ClassCastException
System.out.println("将子类类型自动提升为父类类型:");
A a2 = b;//可以直接赋值,隐式的自动转换
a2.show();

//在向下转型时,使用instanceof操作符进行判断
if(a instanceof B){
System.out.println("a 指向的是 B的对象,可以安全向下转换为B类型");
B b2 = (B)a;

}
if(a instanceof C){
System.out.println("a 指向的是 C的对象,可以安全向下转换为C类型");
C c2 = (C)a;
}
}
}
第二讲 抽象类

一,抽象类

1.有些时候,有些父类中的一些方法,会被每个子类都要重写,

所以此时,父类中这个方法的定义就没有意思。

2.这时,可以将父类中的这个方法定义为"抽象的方法";只有方法声明,没有方法体;

需要一个关键字:abstract

例如:

abstract void show();//直接分号结束,没有大括号;

3.如果父类中,有一个方法是"抽象方法",那么这个类也必须是"抽象的",在类的定义处

需要使用关键字:abstract

4.如果一个类是"抽象类",就意味着这个类"不能被实例化"了。

5.一个抽象类,就是用来做"父类",被其它类"继承"的。

abstract class Person
{
abstract void show();
}
class Student extends Person
{
//重写show
void show(){
System.out.println("我是黑马的一名学生");
}
}
class Teacher extends Person
{
//重写show
void show(){
System.out.println("我是黑马的一名教师");
}
}
class Demo
{
public static void main(String[] args)
{
Person p1 = new Student();
p1.show();//子类

}
}
二,抽象类的特点

1.抽象类和抽象方法,使用关键字:abstract修饰;

2.抽象类中,可以什么都不定义。包括抽象方法;

3.抽象类中的可以有什么东西:

1).成员变量:

2).成员方法;

3).构造方法:

4).抽象方法:

4.子类继承一个抽象类仍然使用:extends ,而且仍然是"单继承"

5.如果一个子类,继承了一个抽象类,那么必须要全部重写父类中的"抽象方法",可以不重写或不全部重写,

那么这个子类也必须是"抽象类"。换句话说:一个抽象类可以继承自一个抽象类;

abstract class Person
{
//成员变量
private int num = 10;
//成员方法
public void show(){
System.out.println("Person --> show()");
}
//构造方法
Person(){
System.out.println("Person的无参构造方法");
}
//抽象方法
public abstract void eat();
public abstract void sleep();
public abstract void method();
}
//一个类,继承自一个抽象类后,必须重写抽象类中的所有抽象方法
class Student extends Person
{
public void eat(){
System.out.println("烤冷面");
}

public void sleep(){
System.out.println("我睡觉");
}
public void method(){
System.out.println("method方法");
}
}
//
abstract class Teacher extends Person
{
//只重写一个方法。那么这个类,也必须是一个抽象类
public void eat(){

}

//其它两个抽象方法没有重写

}

class Demo
{
public static void main(String[] args)
{
//	Person p = new Person();
Person p = new Student();
}
}
第三讲 接口

一,定义

1.当一个抽象类中没有实现的方法,而只有抽象方法时,可以将这个类定义为:接口;

使用关键字:interface

2.接口跟抽象类一样,不能被"实例化",用来做父类的;

3.子类是"实现接口",使用关键字:implements

4.如果一个类实现某个接口,那么必须全部重写接口的抽象方法;

5.接口中可以定义什么:JDK8以前:

1.成员变量:必须是全局常量:必须被声明为:public static final,可以不这样声明,但编译器会自动添加

interface IA{

int num = 10;//隐式的自动声明为:public static final int num = 10;

}

2.成员方法(抽象方法):必须是抽象方法,必须被声明为:public abstract。可以不这样声明,但编译器会自动添加

interface IA{

void show();//隐式的自动声明为:public abstract void show();

}

interface IService
{
abstract void add();
abstract void update();
abstract void delete();
abstract void find();
}
class StudentService implements IService
{
//必须全部重写接口中的抽象方法
public void add(){
}
public void update(){
}
public void delete(){
}
public void find(){
}
}
class Demo
{
public static void main(String[] args)
{
//使用接口多态
IService is = new StudentService();
is.add();//子类的
}
}
二,接口的特点

1.定义接口:关键字:interface

格式:interface 接口名

2.子类实现:关键字:implements

3.一个子类,可以同时实现多个接口。格式:

class SubA implements IA,IB,IC{

}

必须要重写三个接口中的所有抽象方法;

4.一个接口,可以"继承自"另一个接口,而且可以"多继承":使用关键字extends

5.一个抽象类,仍然是实现接口,而且可以实现多个接口,而且可以不重写或不全部重写接口中的方法。因为此类本身就是个"抽象的"

6.一个类可以同时继承自一个父类,并同时实现一个或多个接口:一定要先"继承",后"实现"

三,接口与抽象类的区别

相同点:都不能被实例化;

区别:

1.定义关键字:

1).接口:interface

2).抽象类:abstract class

2.子类使用时:

1).接口:implements(实现):可以同时实现多个接口

2).抽象类: extends(继承):单继承

3.内部成员:

1).接口:

A.成员变量:public static final

B.抽象方法:public abstract

2).抽象类:

A.成员变量

B.成员方法

C.构造方法

D.抽象方法;

4.接口和接口之间:继承关键,可以多继承

抽象类和抽象类之间:继承关系,单继承;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: