一、类的继承格式
在Java中使用extends关键字来完成类的继承关系,格式如下:
class 父类{}//定义父类
class 子类 extends 父类{}//使用extends关键字来实现继承
子类继承父类,可以扩展已有类的功能,子类也称为派生类。
class Person{
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;
}
}
class Student extends Person{
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class Demo{
public static void main(String args[]) {
Student stu = new Student();
stu.setName("张三");//在Student类中没有声明
stu.setAge(30);//在Student类中没有声明
stu.setSchool("清华大学");
System.out.println("姓名:"+stu.getName()+"年龄:"+stu.getAge()+"大学:"+stu.getSchool());
}
}
在Java中继承是有限制的,在Java中继承只能单继承,不能使用多重继承,即一个子类只能继承一个父类,但是允许进行多层继承。即一个子类可以有一个父类,一个父类还可以有一个父类。其次,继承中还存在访问限制。在使用继承时,应该注意:子类不能直接访问和调用父类的私有成员,但是子类可以调用父类中的非私有方法。
class Person{
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;
}
}
class Student extends Person{
public void fun() {
System.out.println("父类中的name属性"+getName());
System.out.println("父类中的age属性"+getAge());
// System.out.println("父类中的name属性"+name);
// System.out.println("父类中的age属性"+age);
}
}
public class Demo{
public static void main(String args[]) {
Student stu = new Student();
stu.setName("张三");
stu.setAge(30);
System.out.println("姓名:"+stu.getName()+"年龄:"+stu.getAge());
}
}
二、子类对象的实例化
在继承的操作中,对于子类对象的实例化也是有要求的。子类对象在实例化之前必须首先调用父类中的构造方法之后再调用子类自己的构造方法。
实际上,这是因为子类的构造方法中隐含了一个super语句,因此将父类称为超类
class Person{
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;
}
}
class Student extends Person{
private String school;
public Student(){
super();//默认隐藏
System.out.println("子类Student中的构造");
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
三、方法的覆写
在继承的关系中存在着方法覆写,所谓方法覆写就是指子类中定义类与父类同名的方法,但是在方法中覆写时必须考虑到权限,即:被子类覆写的方法不能拥有比父类更加严格的访问权限。因此要注意访问权限的严格程度大小关系:private > default > public
因此,当父类的访问权限为public时,子类就不能为其他类型的访问权限,只能是public
class Person{
void print() {
System.out.println("Person--->void print()");
}
}
class Student extends Person{
public void fun() {
System.out.println("Person--->void print()");
}
}
public class Demo{
public static void main(String args[]) {
Student stu = new Student();
stu.print();//这里调用的是子类覆盖的父类方法
}
}
主函数中调用的方法是子类覆盖掉的方法,但是如果想要调用父类的方法,那么需要使用super关键字,super可从子类中访问父类中的内容,如果要访问被覆盖过的方法:super.方法()
class Person{
void print() {//default访问权限
System.out.println("Person--->void print()");
}
}
class Student extends Person{
public void fun() {//public 访问权限
super.print();
System.out.println("Person--->void print()");
}
}
public class Demo{
public static void main(String args[]) {
Student stu = new Student();
stu.print();//这里调用的是子类覆盖的父类方法
}
}
如果同一个方法,当父类访问权限为private,子类访问权限为default时,这种情况不属于方法覆写,而是两个不同的方法。
四、方法覆写和重载的区别
五、super关键字
super表示从子类调用父类中的指定操作,例如:调用属性、方法、构造等,因为在子类实例化的时候会默认调用父类的无参构造,如果希望调用有参构造,则应该子类中明确声明。下面例子中就是在子类中使用super来调用父类中的属性。
class Person{
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;
}
public Person(String name , int age) {
this.setName(name);
this.setAge(age);
}
public String getInfo() {
return "姓名:"+name+"、年龄:"+age;
}
}
class Student extends Person{
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public Student(String name,int age,String school) {
super(name,age);//这里使用super来调用父类的属性
this.school = school;
}
}
public class Demo{
public static void main(String args[]) {
Student stu = new Student("张三",30,"清华大学");
System.out.println(stu.getInfo());
}
}
六、this与super的区别
七、final关键字
可以使用final关键字声明类、属性、方法。
- 使用final声明类不能有子类;
- 使用final声明的方法不能被子类锁覆写;
- 使用final声明的变量即成为常量,常量不可以修改,而且必须为其制定内容
final声明的变量的字母全部采用大写的形式。
全局常量
使用static final关键字联合声明的变量称为全局常量
public static final String INFO="LLLLLLL";
八、抽象类
抽象类概念:包含一个抽象方法的类就称为抽象类
抽象方法:只声明而未实现的方法称为抽象方法,抽象方法必须使用abstract关键字声明
抽象类的定义与使用:
- 包含一个抽象方法的类必须是抽象类
- 抽象类和抽象方法都要使用abstract关键字声明
- 抽象方法只需要声明而不需要实现,不能直接实例化
- 抽象类必须被子类继承,子类(如果不是抽象类)必须覆写抽象类中的全部抽象方法
抽象类的定义格式:
abstract class 抽象类名称{
属性:
访问权限 返回值类型 方法名称(参数){
[return 返回值];
}
访问权限 abstract 返回值类型 方法名称(参数);
//在抽象方法中是没有方法体的,注意分号
}
例子:
abstract class A{
public static final String flage = "zzz";//全局常量
private String name = "aaaaa";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void print();//定义抽象方法
}
class B extends A{//B继承A,因此要将A中的抽象方法覆写
public void print() {
System.out.println("flage="+flage);
System.out.println("姓名:"+super.getName());
}
}
public class Demo{
public static void main(String args[]) {
B b = new B();
b.print();
}
}
问题1.:一个抽象类可以使用final关键字声明吗?
不可以,因为abstract声明的类可以被子类继承且其中的方法也必须被子类覆写,而final声明的不可以被子类继承
问题2.:一个抽象类可以定义构造方法吗?
实际上一个抽象类是允许存在构造方法的,因为抽象类依然使用的是类的继承关系,而且抽象类中也存在各个属性,所以子类在实例化之前肯定是先要对父类进行实例化。
九、接口
如果一个类完全是全局变量和抽象方法组成,就可以将其定义成一个接口。
接口的定义格式:
interface 接口名称{
全局常量;
抽象方法;
}
interface A{
public static fianl String name="zzz";
public abstract void print();
public abstract String getInfo();
}
对于接口来讲,因为其定义的时候已经定义了其组成就是全局常量和抽象方法,因此上面的可以定义为:
interface A{
String name = "zzzz";
void print();
String getInfo();
}
实现接口
接口也需要子类来实现,子类通过implement关键字来实现,并且子类必须覆写接口中的全部抽象方法,一个子类可以同时实现多个接口。
实现格式:
class 子类 implement 接口A,接口B......{
}
继承抽象类实现接口
一个子类可以同时继承抽象类和实现接口。格式如下:
class 子类 extends 抽象类 implements 接口A,接口B,...{}
接口的继承
一个接口不能继承一个抽象类,但是却可以通过extends关键字同时继承多个接口,实现接口的多继承。
格式:
interface 子接口 extends 父接口A,父接口B,...{}