1.什么是继承?
2.为什么继承?
3.怎么继承?
4.继承需要注意一些什么?
最后:一个有趣的demo((使用工具classpy.jar))
1.多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。从个人角度看,继承更多的是描述类与类之间的关系。描述的是一种 is a 的关系,不能为了继承而继承。
2.当两个类在现实世界在上有客观联系,在类中有相同的属性和方法时,我们可以通过继承来实现需要的类。这样做 1.提高了代码的复用性2.提高了代码的可维护性3.为将来的多态埋下了伏笔(做好了前提)
public class Empolyee {
private String name;
private int salary;
public Empolyee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public String getDetails(){
return "Name:"+name+"\nSalary"+salary;
}
}
public class Manager extends Empolyee{
private String department;
public Manager(String name, int salary,String department) {
super(name, salary);
this.department = department;
}
public String getDetails(){
return super.getDetails()+"\nDepartment"+department;
}
}
3.继承是通过extends关键字进行的。看下面的例子:
class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setInt(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
class student extends Person{
//此处不添加任何代码
}
public class ExtDemo{
public static void main(String args[]){
Student stu = new Student();
stu.setName("张三");
set.setAge(30);
System.out.println(stu.getName()+stu.getAge());
}
}
student是子类,继承父类person。复用父类的name、age字段以及相应的方法字段。体现了student is person 的关系。
4.需要注意构造方法、成员权限和方法重写。
(1)成员权限:访问权限控制符
作用: 用于控制被修饰变量、方法、类的可见范围.
public 的访问级别是最高的,其次是 protected、默认和 private.
成员变量和成员方法可以处于4个访问级别中的一个:公开、受保护、默认或私有.
存在继承关系时,父类不可以是 private,因为子类无法继承
顶层类可以处于公开或默认级别,顶层类不能被 protected 和 private 修饰.
局部变量不能被访问控制修饰符修饰 .
下图是在不同情况下各种权限修饰符的作用范围:(子父类的访问权限着重看第三行)
总结:在不同包下面能够访问的权限修饰符只有:public与protected,但是protected必须要有继承关系才能访问。
(2)方法重新(方法覆盖):注意与方法重载的区别
方法重写:在继承关系中,子类重新父类中的某个方法。对于方法的返回值,参数个数,参数类型都和父类一模一样。
方法重载 : 同一个类中出现同名函数,参数列表不同,返回值类型无关。仅仅是函数名相同而已。
(3)构造方法:java 中的构造方法是分层初始化,看下面的例子。
class Fu {
static {
System.out.println("静态代码块Fu");
}
{ System.out.println("构造代码块Fu"); }
public Fu() {
System.out.println("构造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("静态代码块Zi");
}
{ System.out.println("构造代码块Zi"); }
public Zi() {
System.out.println("构造方法Zi");
}
}
Zi z = new Zi(); 请执行结果。
1.遇到Zi z= new Zi();会先将Fu.class和zi.class分别加载到内存,在创建对象,当fu.class加载到内存父类的静态代码会随着Fu.class一起加载,当zi.class加载到内存,子类的讲台代码会随着zi.class一起加载。所以第一个输出,静态代码块Fu,第二个输出静态代码快 Zi
2.走zi的构造方法,因为java是分层初始化的,先初始化父类,再初始化子类,所以先走的父类构造,但是在执行父类构造时,发现父类有构造代码,构造代码块是优先于构造方法执行的。所以第三个输出构造代码块Fu,第四个输出构造方法Fu
3.Fu类初始化结束,子类初始化,第五个输出构造代码块Zi,构造方法Zi
输出结果:
静态代码块:Fu
静态代码块:Zi
构造代码块:Fu
构造方法:Fu
构造代码块:Zi
构造方法:Zi
5.一个有趣的demo来展示java中的继承(使用工具classpy.jar)
public class Empolyee {
private String name;
private int salary;
public Empolyee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public String getDetails(){
return "Name:"+name+"\nSalary"+salary;
}
}
public class Manager extends Empolyee{
private String department;
public Manager(String name, int salary,String department) {
super(name, salary);
this.department = department;
}
public String getDetails(){
return super.getDetails()+"\nDepartment"+department;
}
}
public class TestSuper {
public static void main(String[] args) {
Manager m =new Manager("Tom", 100, "IT");
System.out.println(m.getDetails());
}
}
1.Employee的成员变量私有,在Manager类中没有继承。如下图:
图1和图2是对两个类字节码的详细解释。可以看出来对于private成员,并未继承。
(2)程序能正常执行,输出项中 姓名、工资、部门信息健全。是 因为java进行类构造时候,先构造父类再构造子类,我们使用super()调用了父类的成员变量和方法。
(3)本demo主要向读者推荐classpy.jar工具,为大家将来查看类信息准备。