java 继承

继承

1.为什么要继承?
2.继承怎么实现?
3.继承的特点是什么?
4.继承之后如何访问属性和方法?
5.继承时的访问控制符
6.继承后对象的初始化流程
7.继承时的构造方法的特点
8.super
9.方法的覆盖
为什么要继承?
简化代码,形成体系,给多态提供前提,实现对类的复用,是提高代码重复可用性的一种重要方式
 定义:
class A{
...
}
class B extends A{
...
}
为什么要使用继承呢?假设我们定义了多个类,而在这些类中,有相同的成员变量,方法。如果我们一个个去写的话,不仅浪费时间,而且也造成代码冗余。这时,我们可以将这些类中的共有属性提取到一个新的类中,让其他类去继承该类,从而调用其中的方法属性,该类称为其他类的父类(基类、超类),其他类称为该类的子类。
继承的原则:子类和父类是一种包含的关系;A is B 就可以继承,即说法要符合常规,父类的范围更广。
 
继承怎么实现?
子类 extends 父类
 
 继承的特点是什么?
1.跟C++不同,java的继承是单一继承,一个子类只能有一个父类。一个父类可以有多个子类
2.java可以多层继承,子类继承父类,父类同样可以作为其他类的子类。
 
继承之后如何访问属性和方法?
关于访问控制符(public,protected,private,default):
1.在同包中,在没有任何关系的类中,可以访问其他类的非私有的成员
2.在同包中,在子类中不能访问父类的私有方法和私有属性

 

3.在不同包中,要继承不同包的父类,父类必须是public的,并且在子类的内部可以访问父类的public和protected修饰的成员
我们首先创建2个包:com.epilogue.blog和com.epilogue.blog2
com.epilogue.blog包中创建一个Person类和一个Women(继承Person)类
package com.epilogue.blog;

class Person {//不添加public修饰符

	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
			this.age = age;
	}

	void print() {
		System.out.println("name:" + name + "\nage:" + age);
	}
}

 

package com.epilogue.blog;
public class Women extends Person {
	void print() {
          //此处可以用super.父类的非私有方法和非私有属性 System.out.println("class women"); } }

  package com.epilogue.blog2中创建一个Man类(继承Person类)

 

这个时候就报错了,因为Person类是默认default控制修饰符的,而我们在不同包时,它Person类要被继承,就必须定义为public的。

4.在不同包中,没有继承关系的类中,只能访问其他包中的public类的public成员
 
只有Public的类才能被其他包访问,前提是导入包。public修饰的类名必须和文件名前缀一致,一个.java文件只能有一个public修饰的类
 
 
6.继承后对象的初始化流程
父类的静态块--》子类的静态块--》父类的初始化块--》父类的构造块--》子类的初始化块--》子类的构造块
 A--》B表示优先于A优先于B执行的意思
public class Demo {

	public static void main(String[] args) {
		N n=new N();
	}

}

class M{
	static{
		System.out.println("父类的静态块");
	}
	{
		System.out.println("父类的初始化块");
	}
	public M(){
		System.out.println("父类的构造块");
	}
}
class N extends M{
	static{
		System.out.println("子类的静态块");
	}
	{
		System.out.println("子类的初始化块");
	}
	public N(){
		System.out.println("子类的构造块");
	}
}

  

  执行结果为:

父类的静态块
子类的静态块
父类的初始化块
父类的构造块
子类的初始化块
子类的构造块

可以看出,static块会最先被执行,且只执行一次;创建一个子类对象时,会自动调用父类的构造方法。

继承时的构造方法的特点:
1.子类不能继承父类的构造方法

 

2.在子类的构造方法的第一句会默认调用父类的无参构造,就是super();如果父类没有无参构造,就会报错
我们首先修改子类S的代码,让其构造方法继承父类super(),

在main方法中创建对象

S s = new S();

则输出结果为

“父类的构造方法”

然后,我们将子类构造方法的代码注释掉,可以发现。仍然会输出“父类的构造方法”,这是因为子类的构造方法的第一句会默认调用父类的无参构造,所以父类的构造方法会优于子类执行。我们修改父类的构造方法,为其添加一个参数

 

 

这时,就会报这样一个错误

 

 

3.可以在子类构造方法的第一句自己调用super(参数),来调用父类的有参构造,前提是父类提供了相同参数的构造方法

错误提示我们需要为子类添加一个有参数的构造方法来继承父类,即:

 

 

4.super()或者是super(参数)必须是子类构造的第一行代码

5.super()或者super()参数只能调用一次

 

super

1.如果子类中有和父类相同的属性,可以在子类的方法中通过super.属性的方式访问父类继承的属性

package com.epilogue.blog;

 

public class Demo1 {

 

        public static void main(String[] args) {

                S s = new S();

                s.p();//调用p()方法

        }

 

}

 

class S extends F {

        void p() {//子类中定义方法p()

                super.name = "epilogue";//通过super.属性/方法调用父类的属性方法

                super.age = 22;

                super.print();

        }

 

}

 

class F {

        String name;//定义2个变量

        int age;

 

        void print() {

                System.out.print("name:" + name + "\nage:" + age);

        }

}

  

输出结果为

name:epilogue
age:22

2.super只能在子类的内部调用父类的属性和方法,不能应用在静态方法中



 

方法的覆盖:方法的重写

1.子类中的方法和父类的方法同名同参同返回值

2.重写方法后,子类对象调用的是重写后的方法

3.重写方法时,子类方法的访问权限不能低于父类方法的访问权限

public---protecter--default---private

重写方法时,子类不能将父类的静态方法覆盖成非静态

 

方法的重载和方法的重写

重载指的是,同一个类中,同名方法,有不同的参数

 

 

final关键字

1.修饰局部变量,局部变量必须初始化,值不能被修改了;

2.修饰非静态成员变量,成员变量也必须修饰初始化,初始化后值不能再被修改了。

3.非静态成员变量初始化:

1)int b=0;

2)在非静态初始化块中

3)在构造方法中

3.修饰静态成员变量,也必须初始化,初始化后值不能再被修改了

静态成员变量初始化:

1)定义的同时

2)静态块

4.修饰方法:可以被继承,不能被子类覆盖

5.修饰类:这个类就不能被继承

 

转载请注明:http://www.cnblogs.com/epilogue/p/5672163.html 

posted @ 2016-07-16 08:40  Epilogue  阅读(198)  评论(0编辑  收藏  举报