子类与父类:
多个类中具有相同的属性和行为时,将这些内容拿出来单独放到一个类中,其他多个类无需再定义这些属性和行为,只需要 继承这个类即可。单独的这个类称为父类,基类或超类。多个类被称为子类或者派生类。继承以后,可以在父类的基础上加 入自己的新成员。
继承:
格式:class 子类名 extends 父类名 {}
好处:
1.提高了代码的复用性。
2.提高了代码的维护性。
3.让类与类之间有了关系,是多态的前提。(同时也是弊端,增强了类的耦合性)
弊端:
增强了类的耦合性。
开发原则:低耦合,高内聚。
耦合:类与类的关系。
内聚:自己完成某项事情的能力。
使用继承之前:
package Person;
public class Student {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
package Person;
public class Soldier {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
package Person;
public class ExtendsDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//学生
Student s = new Student();
s.eat();
s.sleep();
//军人
Soldier s2 = new Soldier();
s2.eat();
s2.sleep();
}
}
使用继承之后:
package Person;
public class Person {
public void eat() {
System.out.println("吃饭");
}
public void sleep() {
System.out.println("睡觉");
}
}
package Person;
public class Student extends Person {
}
package Person;
public class Soldier extends Person {
}
package Person;
public class ExtendsDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
//学生
Student s = new Student();
s.eat();
s.sleep();
//军人
Soldier s2 = new Soldier();
s2.eat();
s2.sleep();
}
}
特点:
1.java中只支持单继承,不支持多继承。(其他语言有的支持多继承,例如C++,格式extends 父类1,父类2,.....)
2.支持多层继承(形成继承体系)。
3.子类只能继承父类中的非私有成员,但可以通过父类的成员方法调用父类的私有成员变量。
4.子类不能继承父类的构造方法,但可以通过super关键字访问父类的构造方法。
多层继承:
package GrandFather;
public class GrandFather {
public void show() {
System.out.println("GrandFather");
}
}
package GrandFather;
public class Father extends GrandFather {
public void method() {
System.out.println("Father");
}
}
package GrandFather;
public class Son extends Father {
public void show2() {
System.out.println("Son");
}
}
package GrandFather;
public class ExtendsDemo1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.show();
s.method();
s.show2();
}
}
怎样判断是否使用继承:
采用假设法:如果有两个类A,B,只有当A是B的一种或者B是A的一种的时候,就可以考虑使用继承。
注意:不要为了部分功能而去继承。
package Number;
public class Father {
int num1 = 100;
int num2 = 200;
public void Number() {
System.out.println(num1);
System.out.println(num2);
}
}
package Number;
public class Son {
int num2 = 200;
int num3 = 400;
public void Number1() {
System.out.println(num2);
System.out.println(num3);
}
}
package Number;
public class ExtendsDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.Number1();
Father s1 = new Father();
s1.Number();
}
}
package Number;
public class Son extends Father {//虽然继承了num2但是多了num1
int num2 = 200;
int num3 = 400;
public void Number1() {
System.out.println(num3);
}
}
package Number;
public class ExtendsDemo2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//输出结果多了num1
Son s = new Son();
s.Number();
s.Number1();
}
}
继承中父类成员变量与子类成员变量之间的关系:
子类成员变量与父类成员变量名相同:(就近原则)
1.首先在子类的局部范围查找。
2.然后在子类的成员范围查找。
3.最后在父类的成员范围内查找,这里不考虑多层继承的情况。(不可能访问到父类的局部范围)。
4.如果都没有,报错。
继承中构造方法之间的关系:
1.子类构造方法默认访问父类构造方法。(因为子类会继承父类的数据,可能还会使用父类的数据, 所以子类 初始化之前,一定要先完成父类的初始化)。
2.子类的构造方法的第一条默认语句为super();
package Father;
public class Father {
public Father() {
System.out.println("Father无参构造方法");
}
public Father(String name) {
System.out.println("Father的有参构造方法");
}
}
package Father;
public class Son extends Father {
public Son() {
//子类的构造方法中第一句默认为super();
System.out.println("Son的无参构造方法");
}
public Son(String name) {
//子类的构造方法中第一句默认为super();
System.out.println("Son的有参构造方法");
}
}
package Father;
public class ExtendsDemo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
System.out.println("-----------");
Son s2 = new Son("周杰伦");
}
}
3.如果父类没有无参构造方法;
解决方法:
1.在父类中加一个无参构造方法。
2.通过super调用父类的有参构造方法。
3.通过this访问本类的其他构造方法(被访问的方法中必须要访问了父类的构造方 法,否则父类数据就没有初始化)。
注意:this(....)或则super(.....)必须出现在第一条语句上。如果不是在第一条语句上,就可能对 父类进行了多次初始化。
通过super访问父类的有参构造方法:
package Father;
public class Father {
public Father(String name) {
System.out.println("Father的有参构造方法");
}
}
package Father;
public class Son extends Father {
public Son() {
super("雷锋");
System.out.println("Son的无参构造方法");
}
public Son(String name) {
super("雷锋");
System.out.println("Son的有参构造方法");
}
}
通过this访问本类中的其他构造方法:
package Father;
public class Son extends Father {
public Son() {
super("雷锋");
System.out.println("Son的无参构造方法");
}
public Son(String name) {
this();//通过this访问本类中的其他构造方法,被访问的构造方法中必须访问了父类的构造方法。
System.out.println("Son的有参构造方法");
}
}
继承中成员方法之间的关系:
子类中方法声明和父类中方法声明一样的使用:
通过子类对象访问一个方法:(就近原则)
1.先找子类中看有没有这个方法。有就使用。
2.然后找父类中看有没有这个方法。有就使用。(这里不考虑多层继承)。
3.如果都没有,就报错。
package Father;
public class Father {
public void show() {
System.out.println("Father的成员方法");
}
}
package Father;
public class Son extends Father {
public void show() {
System.out.println("Son的成员方法");
}
}
package Father;
public class ExtendsDemo3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s = new Son();
s.show();//就近原则,运行结果为:Son的成员方法。
}
}
方法重写:(override)
概述:子类中出现了和父类声明一模一样的方法声明,也被称为方法覆盖或则方法复写。
特点:如果方法名不同,有就调用对应的方法。如果方法名相同,最终使用的是子类自己的。
应用:当子类需要父类中的功能,而子类又需要有自己的特有的内容时,可以重写父类的方法,这样既沿袭了 父类的功能,又定义了子类特有的功能。
注意:
1.父类中的私有方法不能被子类重写。
2.父类中的静态方法在子类中重写时也要用静态方法(其实这个不算严格意义上的方法重写)。
3.子类重写父类时访问权限不能降低,只能大于等于。(子类重写父类方法时声明最好一模一样)。
方法重载:(overload)
概述:同一个类中出现的方法名相同,参数列表不同的现象。
注意:方法重载能改变返回值的类型,因为它和返回值类型无关。
方法重写:
package Phone;
public class Phone {
public void show() {
System.out.println("打电话");
}
}
package Phone;
public class NewPhone extends Phone {
public void show() {
super.show();//方法重写之后用super访问父类的方法
System.out.println("玩游戏");
}
}
package Phone;
public class ExtendsDemo4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
NewPhone s = new NewPhone();
s.show();
}
}