java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立父子关系。子类能继承父类的非私有成员,子类对象是由父类子类共同完成的(子类对象包含父类成员,但无法调用非私有成员)。
public class A {
public int i;
public void print1(){
System.out.println("===print1===");
}
}
public class B extends A {
//子类可以继承父类的私有成员
public void print3(){
System.out.println(i);
print1();
}
}
public class Test {
public static void main(String[] args) {
B b = new B();//b对象是由AB两个设计图共同创建的
System.out.println(b.i);
b.print1();
}
}

权限修饰符
修饰符 | 在本类 | 同一个包的其他类里 | 任意包下的子类里 | 任意包下的任意类型 |
---|---|---|---|---|
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
- protected可以在任意包下的子类A里访问,但不能在非子类B中通过A类的对象访问
单继承
一个类只能继承一个父类,Java中的类不支持多继承,但支持多层继承。
class A {};//extends Object{},Object类是所有类的祖宗类
class B extends A {};
class C extends B {};
方法重写
当子类觉得父类某个方法不管用,子类可以重新写一个参数一样的方法,子类可以重写一个参数列表一样的方法,称为方法重写。重写后方法的访问遵循就近原则。
- 重写小技巧:使用Override重写,可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
- 子类重写父类方法时,访问权限必须大于等于父类该方法的权限(public>protected>缺省)
- 重写方法返回值类型,必须与被重写方法返回值一样,或者范围更小。
- 私有方法,静态方法不能被重写,如果重写会报错的。
public class A {
public void print1(){
System.out.println("111");
}
public void print2(int a,int b){
System.out.println("111111");
}
}
public class B extends A{
@Override
public void print1(){
System.out.println("666");
}
@Override
public void print2(int a,int b){
System.out.println("666666");
}
}
常见应用场景
子类重写Object中的类方法,以便返回对象的内容。
//object类中的toString()方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
创建实体类Student
public class Student {
private int age;
private String name;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
······
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}
public class Test {
public static void main(String[] args) {
Student s=new Student("播妞",19);
System.out.println(s);//Student [age=19, name=播妞]
}
}
子类中访问其他成员的特点
在子类方法中访问成员遵循就近原则,如果在子父类中出现了重名的成员,会优先选择子类的;如果此时一定要在子类中使用父类成员需要使用super关键字。
public class F {
String name="父类名称";
public void print1(){
System.out.println("==父类的print方法执行==");
}
}
public class Z extends F{
String name="子类名称";
public void showname() {
String name="局部名称";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
public void print1(){
System.out.println("==子类的print方法执行==");
}
public void showMethod(){
print1();
super.print1();
}
}
public class Test {
public static void main(String[] args) {
Z z=new Z();
z.showname();
/*局部名称
子类名称
父类名称*/
z.showMethod();
/*==子类的print方法执行==
==父类的print方法执行==*/
}
}
子类构造器
子类的全部构造器都会先调用父类的构造器,再执行自己的。
public class F {
public F() {
System.out.println("父类的无参构造器执行了");
}
}
子类的所有构造器都会调用父类的无参构造器,如果父类没有无参构造器会报错。或者在子类构造器里第一行用super(...)调用父类的有参构造器。
public class Z extends F{
public Z() {
super();//默认存在
System.out.println("子类的无参构造器执行了");
}
public Z(String name) {
super();//默认存在
System.out.println("子类的有参构造器执行了");
}
}
public class Test {
public static void main(String[] args) {
Z z=new Z();
/* 父类的无参构造器执行了
子类的无参构造器执行了*/
Z z2=new Z("wasd");
/*父类的无参构造器执行了
子类的有参构造器执行了*/
}
}
常见应用案例:
public class Test2 {
public static void main(String[] args) {
Teacher t = new Teacher("李四",36,"Java");
}
}
class Teacher extends People{
private String skill;
public Teacher(String name, int age, String skill) {
super(age, name);
this.skill = skill;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
class People{
private String name;
private int age;
public People() {
}
public People(int age, String name) {
this.age = age;
this.name = name;
}
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;
}
}
兄弟构造器
在任意类的构造器中,可以用this(...)调用兄弟构造器。this(...)和super(...)不能同时写,且this(...)也要写在第一行。
public class Test3 {
Student s1=new Student("李四",24);
}
class Student{
private String name;
private int age;
private String schoolname;
public Student() {
}
public Student(String name, int age) {
this(name, age, "WASD");
}
public Student(String name, int age, String schoolname) {
this.name = name;
this.age = age;
this.schoolname = schoolname;
}
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;
}
public String getSchoolname() {
return schoolname;
}
public void setSchoolname(String schoolname) {
this.schoolname = schoolname;
}
}