黑马程序员---多态

 ------<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.接口和接口之间:继承关键,可以多继承
 抽象类和抽象类之间:继承关系,单继承;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值