黑马程序员 封装特性之继承和多态

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、继承

1、多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
2、多个类可以称为子类,单独这个类称为父类或者超类。
3、子类可以直接访问父类中的非私有的属性和行为。
4、通过extends 关键字让类与类之间产生继承关系。

好处: 

1:提高了代码的复用性。 

2:让类与类之间产生了关系,提供了另一个特征多态的前提。

形式:

classSubDemoextends Demo{}

 

<span style="font-size:18px;">class Personnel
{
	String name;//姓名
	String sex;//性别
	int age;		//年龄
	void show(){
		System.out.println("大家好,我叫:" + name + 
							",性别:" + sex + 
							",年龄:" + age);
	}
}
class Student extends Personnel{
	String classNo;	//学号
}
class Teacher extends Personnel{
	String subject;//学科
}
class Employee{
	String dept;	//部门
}
class Demo 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.name = "刘德华";
		stu.sex = "男";
		stu.age = 20;

		stu.show();

		Teacher tea = new Teacher();
		tea.name = "章子怡";
		tea.sex = "女";
		tea.age = 18;
		tea.show();
	}
}
</span>
3、方法的重写(Override)
1)当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,
这样,即沿袭了父类的功能,又定义了子类特有的内容。
2)重写的规则:
子类方法的:返回值类型、方法名、参数列表:必须完全相同;
如果只有返回值类型、方法名:编译可以通过,此方法认为是子类自己的方法
如果只有方法名、参数列表相同,返回值不同:编译错误.不能重写,要求返回值类型必须相同;

4、super关键字
1.一个子类中自用会拥有个父类的引用,就是super;
2.当实例化子类对象时,会先实例化一个父类对象,会隐式的调用父类默认的构造方法,会在子类的
 构造方法的第一句话添加一句:super();
3.如果父类没有默认构造方法时,子类必须显示的调用父类的带参构造方法,需要使用关键字super();
4.当子类覆盖了父类的成员时,在子类中可以使用super.XXX来访问父类中被覆盖的成员;
class Student extends Personnel{
	public int num = 20;//可以,子类的成员覆盖父类的成员
	private String no = "b";
	Student(){
		super();
		System.out.println("构造了一个Student = " + no );
	}
	Student(String name){
		super(name);
		System.out.println("带一个参数的Student构造器");
	}
	void show(){
		
		int num = 30;
		System.out.println("num = " + num);//使局部变量
		System.out.println("this.num = " + this.num);//本类自己的
		System.out.println("super.num = " + super.num);//父类的
	}
	//重写了父类的say();
	//@Override//重写标记,编译器按照重写规则验证方法,不符合重写规则的方法,不能通过编译;

	void say(){super.say();
		
		System.out.println("我是传智播客的一名学生!我骄傲!!");
	}
	//可以编译,和父类的void say()不是重写关系,是属于两个方法
	void say(String str){
		
		System.out.println("我是传智播客的一名学生!我骄傲!!");
	}
	//编译失败,方法名、参数列表完全相同,但返回值类型不同,要求返回值类型必须相同;
/*	int say(){

	}
*/
}
class Teacher extends Personnel
{
	Teacher(){
		super("");
		System.out.println("构造了一个Teacher");
	}
}
class Demo 
{
	public static void main(String[] args) 
	{
		Student stu = new Student("刘德华");
		stu.say();
	
	//	Teacher tea = new Teacher();
	}
}

f inal特点:
1:这个关键字是一个修饰符,可以修饰类,方法,变量。
2:被final修饰的类是一个最终类,不可以被继承。
3:被final修饰的方法是一个最终方法,不可以被覆盖。
4:被final修饰的变量是一个常量,只能赋值一次。

  

 

class Const{
	public static final double PI = 3.14159;
}
class Personnel{
	final int num;
	final static int num2 = 20;
	Personnel(){
		num = 10;
	}
	String name;
	final void say(){
		System.out.println("我是传智播客的一员");
	}
	
}
class Student extends Personnel{
	//不能重写父类的final方法
/*	void say(){
	}
	*/

}
class Demo 
{
	public static void main(String[] args) 
	{
		System.out.println(Const.PI);
	}
}

抽象

抽象定义:

抽象就是从多个事物中将共性的,本质的内容抽取出来。

例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。

抽象类:

Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。

抽象方法的由来:

多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。


1:抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。 

2:抽象方法只定义方法声明,并不定义方法实现。 

3:抽象类不可以被创建对象(实例化) 

4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。 

5: 抽象类只能单继承。 


抽象类的细节: 

1:抽象类中是否有构造函数?有,用于给子类对象进行初始化。

 2:抽象类中是否可以定义非抽象方法? 

可以。其实,抽象类和一般类没有太大的区别,都是在描述事物,只不过抽象类在描述事物时,有些功能不具体。所以抽象类和一般类在定义上,都是需要定义属性和行为的。只不过,比一般类多了一个抽象函数。而且比一般类少了一个创建对象的部分。 

3:抽象关键字abstract和哪些不可以共存?final , private , static  

4:抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。


<span style="font-size:18px;">abstract class Personnel
{
	abstract void say();
}
class Student extends Personnel
{
	//必须要重写父类的抽象方法
	void say(){
		System.out.println("我是传智播客的一名学生");
	}
}
class Teacher extends Personnel
{
	//必须要重写父类的抽象方法
	void say(){
		System.out.println("我是传智播客的一名教师");
	}
}
//一个抽象类可以继承另一个抽象类
abstract class B extends Personnel
{

}
class Demo 
{
	public static void main(String[] args) 
	{
		Student stu = new Student();
		stu.say();
	}
}</span>

接 口

格式:

    interface {}

接口中的成员修饰符是固定的。
成员常量:public static final
成员函数:public abstract
发现接口中的成员都是public的。
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。

接口的特点

接口是对外暴露的规则

接口是程序的功能扩展

接口的出现降低耦合性

接口可以用来多实现

类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。

接口与接口之间可以有继承关系


抽象类和接口的区别:

1:抽象类只能被继承,而且只能单继承。 

接口需要被实现,而且可以多实现。  

2:抽象类中可以定义非抽象方法,子类可以直接继承使用。 

接口中都有抽象方法,需要子类去实现。

3:抽象类使用的是  is a 关系。 

接口使用的 like a 关系。 

4:抽象类的成员修饰符可以自定义。 

接口中的成员修饰符是固定的。全都是public的。    

 


interface IA{
	void f1();
	void f2();
}
interface IB{
	void f2();
	void f3();
}

interface IC extends IA,IB
{
	void f4();
}
class C
{
}
class A extends C implements IC{//多实现
	public void f1(){
	}
	public void f2(){
	}
	public void f3(){
	}
}
class Demo 
{
	public static void main(String[] args) 
	{
		System.out.println("Hello World!");
	}
}


 

、多态

函数本身就具备多态性,某一种事物有不同的具体的体现。 

体现:父类引用或者接口的引用指向了自己的子类对象。//Animal a = new Cat(); 

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

多态的弊端:当父类引用指向子类对象时,虽然提高了扩展性,但是只能访问父类中具备的方法,不可以访问子类中特有的方法。

多态的前提: 

1:必须要有关系,比如继承、或者实现。

 2:通常会有覆盖操作。  

class Animal
{
	void run(){
		System.out.println("跑");
	}
}
class Cat extends Animal
{
}
class Dog extends Animal
{
}
class  Demo
{
	public static void main(String[] args) 
	{
		//正常写法:
		Cat cat = new Cat();
		cat.run();
		//多态的写法:
		//一个父类的引用指向了它的一个子类的对象
		Animal anmObj = new Cat();
		anmObj.run();

		Animal anmObj2 = new Dog();
		anmObj2.run();
	}
}

名内部类

没有名字的内部类。就是内部类的简化形式。一般只用一次就可以用

这种形式。匿名内部类其实就是一个匿名子类对象。想要定义匿名内部类:需要前提,内部类必须继承一个类或者实现接口。 

匿名内部类的格式:new 父类名&接口名(){ 定义子类成员或者覆盖父类方法 }.方法。

  匿名内部类的使用场景: 

当函数的参数是接口类型引用时,如果接口中的方法不超过3个。可以通过匿名内部类来完成参数的传递。 

其实就是在创建匿名内部类时,该类中的封装的方法不要过多,最好两个或者两个以内。  

interface IA{
	void show();
}
class Demo {
	public static void main(String[] args){
		fun(
			new IA(){
				//重写的方法
				public void show(){
					System.out.println("HelloWorld");
				}
			}
		);
		fun3(
			new IA(){
				//重写方法
				public void show(){
					System.out.println("你好中国!");
				}
			}
		);
	}

	public static void fun(IA aObj){
		aObj.show();
	}
	public static void fun3(IA aObj){
		aObj.show();
	}


}









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值