首页 > 代码库 > 黑马程序员——java基础--面向对象--继承

黑马程序员——java基础--面向对象--继承

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

继承:
1.当一个类中包含了另一个类的所有变量个方法时,但另一个类中不包含另一个类的所有变量和方法时,表示范围比较小的就可以作为另一个的父类。
集合表示:A属于B,B不属于A,A就可以作为B的父类,B继承A
2.当只是为了获取其他类的功能的时候,不能为了简化代码而继承。
3.必须是类与类之间的所属关系才可以继承,所属关系看前面集合
继承的特点:
1.不支持多继承,只支持单继承:
多继承的话容易产生安全隐患:

class A{
		Demo{
		System.out.println("a");
		}
	}	
	class B{
		Demo{
		System.out.println("b");
		}
	}
	class C extends A,B{
		C c = new c();
		c.Demo();
	}

这时候C就会出现选择错误,不知道要调用A还是要调用B。
2.继承提高了代码的复用性
3.让类与类之间产生了关系,有了这关系,才有了多态的特性。


class person{
	int age;
 	String name;
	}
class student extends person{
	void study(){
	System.out.println("good student");
	}
}
class work extends person{
	void work(){
		System.out.println("good worker");
	}
}
public class extendsDemo{
	public static void main(String[] args){
		student s = new student();
		s.name = "Archer";
		s.age = 21;
		System.out.println("age:"+age+"name:"+name);
		s.work();
		work w = new work();
		w.work();
	}
}
	
java支持多层继承。也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。
那么在具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象,
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象使用功能。

子类与父类出现后,类中的成员都有哪些特点:
1.成员变量
当子父类中出现一样的属性时,子类类型的对象,调用该属性,值是子类的属性值

class student{
	int num = 4;
	study(){
		System.out.println("good study");
	}
	show(){
	System.out.println(num);
	}
}
class smallstudent extends student{
	int num = 5;
	show(){
	System.out.println(num);
	}
}
public class extendsDemo{
	public static void main(String args[]){
		new smallstudent().show();//输出的值为5,不是4
	}
}
如果想要调用父类中的属性值,需要使用关键字super
this和super的区别:
this:代表是本类类型的对象引用
super:代表的是子类所属父类中的内存空间的引用
注意,字父类中通常不会出现同名的成员变量,因为父类中只要定义了,子类就不用再定义了,直接继承过来就可以了。
super关键字。

class student{
	int num = 4;
	study(){
		System.out.println("good study");
	}
	show(){
	System.out.println(num);
	}
}
class smallstudent extends student{
	int num = 5;
	show(){
	System.out.println(super.num);//输出的是父类的值,也就是4
	}
}
public class extendsDemo{
	public static void main(String args[]){
		new smallstudent().show();//输出的值为4
	}
}

2.成员函数
当子父类中出现了一模一样的方法时,建立子类的对象会运行子类中的方法,好像父类中的方法都被覆盖掉一样,所以这种情况,是函数的另一个特性--覆盖(重写)
什么时候使用覆盖呢?
当一个类的功能需要修改时,可以通过覆盖来实现。
3.构造函数
发现子类构造函数运行时,先运行父类构造函数,为什么呢?
子类的所有构造函数中的第一行,其实都有一条隐身的语句super();
super():表示父类的构造函数,并会调用参数相对应的父类中的构造函数,而super():是在调用是在调用父类中的空参数构造函数。
为什么子类对象初始化时,都需要调用父类中的函数,也就是为什么子类构造函数的第一行要加入这个super()?
因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。
class student{
	student(){
	System.out.println("student");
	}
}
class smallstudent extends student{
	smallstudent(){
	System.out.println("smallstudent");
	}
}
public class extendsDemo{
	public static void main(String args[]){
		smallstudent s = new smallstudent();
		s.smallstudent();//输出是student
				//	smallstudent
	}
}
所以子类构造函数实例化的过程中是先访问父类的构造函数。
注意事项:
class student{
	student(){
	System.out.println("student");
	}
	student(int n){
	System.out.println("4");
	}
}
class smallstudent extends student{
	smallstudent(){
	//这里是super关键字
	System.out.println("smallstudent");
	}
	smallstudent(int m){
	//这里可以是this关键字,也可以是super关键字
	System.out.println("5");
	}

}
public class extendsDemo{
	public static void main(String args[]){
		smallstudent s = new smallstudent();
		s.smallstudent();
				
	}
}
但是如果父类没有空参数的构造函数,这样就需要给子类手动在第一行添加super();了。
class student{
	student(int n){
	System.out.println("4");
	}
}
class smallstudent extends student{
	smallstudent(){
	super(3);
	System.out.println("smallstudent");
	}
	smallstudent(int m){
	super(4);
	System.out.println("5");
	}

}
public class extendsDemo{
	public static void main(String args[]){
		smallstudent s = new smallstudent();
		s.smallstudent();
				
	}
}

不然会报错,为什么必须是第一行呢,因为构造函数是为了初始化,如果放在后面的话,子类先初始化,父类再初始化,就会把子类的值给更改,所以初始化的动作要先完成。
在方法覆盖时,注意两点:
1子类覆盖父类时,必须保证,子类方法的权限必须大于等于父类方法权限实现继承,否则,编译失败。
2.覆盖时,要么都静态,要么都不静态,因为静态只能覆盖静态。
函数默认的权限是package,他是介于private和public之间的。
private、public、protected权限大小:
private:只能由1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。但不能被该类的对象访问。
public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。
继承的一个弊端,打破了类的封装性,对于一些类,或者是类中的功能,是需要被继承的,或者是重写的,怎么解决呢?
用关键字:final
final的特点:
1.这个关键字是一个修饰符,可以修饰类,方法和变量
2.被final修饰的类是一个最终类,不可以被覆盖,不可以被继承
3.被final修饰的方法是一个最终的方法,不可以被覆盖
4.被final修饰的变量是一个常量,只能赋值一次

class student{
	final showt(){
	System.out.println("student");
	}//这个方法在不可以被修改
}
class smallstudent extends student{
	smallstudent(){
	System.out.println("smallstudent");
	}
}
public class extendsDemo{
	public static void main(String args[]){
		final PI = 3.14; //这个和c语言中的define有点像,和const更相似
		smallstudent s = new smallstudent();
		s.smallstudent();
	}
}
抽象:
	什么是抽象?
	不具体,看不明白,抽象类表象体现
	在不断抽取过程中,将共性内容中的方法申明抽取,但是方法是不一样的,没有抽取,这是抽取到的方法,并不是具体的,需要被指定关键字abstract所标示,申明为抽象方法。
	抽象方法所在类一定要标示为抽象类,也就是说该类需要被abstract关键字所修饰
class student{
	study(){
	System.out.println("study");
	}	
}
class smallstudent extends student{
	study(){	
	System.out.println("study english");
	}
}
class bigstudent extends student{
	study(){
	System.out.println("study code");
	}
}
ppublic class abstractDemo{
	public static void main(String args[]){
	}
}
这时候smallstudent和bigstudent中都用到了study方法,但是功能里面具体的实现不一样,再继承student类就没有什么意义,这时候就需要使用抽象类。

abstract class student{
	abstract study();//这时候就只有方法,却没有方法体
}
class smallstudent extends student{
	study(){	
	System.out.println("study english");
	}
}
class bigstudent extends student{
	study(){
	System.out.println("study code");
	}
}
ppublic class abstractDemo{
	public static void main(String args[]){
	}
}
如果抽象类中包含多个抽象方法,子类必须对全部的抽象方法初始化,否则会出错。
抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。


抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
abstract 关键字,和哪些关键字不能共存。
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
可是抽象方法运行没意义。
抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化

练习:员工有姓名,员工号,工资,经理也属于员工,但是他有奖金。
分析:
1.必须要有一个员工类
2.经理属于员工,但是不完全属于,他有自己的特殊属性。
3.员工类必须的属性:name/id/gongzi
4.经理附加属性:bonus

class Employee{
	private String name;
	private String id;
	private int gongzi;
	// 初始化
	Employee(String name, String id, int gongzi){
		this.name = name;
		this.id = id;
		thi.gongzi = gongzi;
		}
	public abstract  work();//没有方法体
	}
class Manage extends Employee{
	private int bonus;
	Manage((String name, String id, int gongzi, int bonus){
		super(name,id,gongzi);
		this.bonus = bonus;
		}
	public void work(){
		System.ut.println("manage work");
		}//区别
}
class pro extends Employee{
	pro((String name, String id, int gongzi){
		super(name,id,gongzi);
		}
	public void work(){
		System.ut.println("pro work");
		}
}



黑马程序员——java基础--面向对象--继承