继承是面向对象的三大特点之一。
那么,何为继承?
一个类的对象可以使用另一个类的对象中的成员,这种关系就称之为继承。
一:继承格式
继承关键字extends。
/**
* 人类
*/
class person
{
}
/**
* 学生类
*/
class student extends person
{
}
二:继承的优缺点
优点
1:提高了代码的复用性
2:让类与类之间产生了继承的关系,这是构成多态的前提条件。
3:减少代码冗余,增强类的功能扩展性。
缺点
提高了代码的耦合性。在开发中我们遵循:高内聚,低耦合的原则。
高内聚:指一个类的功能越强越好
低耦合:指一个类的关系越少越好
三:继承的特点
1:java只支持单继承,不可以多继承。
/**
* 父亲类
*/
class fu
{
}
/**
* 儿子类
*/
class zi extends fu
{
}
2:java类可以多层继承
/**
* 爷爷类
*/
class ye
{
}
/**
* 父亲类
*/
class fu extends ye
{
}
/**
* 儿子类
*/
class zi extends fu
{
}
3:java类不支持循环继承
/**
* 爷爷类
*/
class ye extends zi
{
}
/**
* 父亲类
*/
class fu extends ye
{
}
/**
* 儿子类
*/
class zi extends fu
{
}
这样写是不可以的。
四:继承后:成员变量、成员方法的访问特点
1:子类不能继承父类中被private关键字所修饰的成员变量和成员方法。
2:子类不能继承父类的构造方法。
3:在子类方法中访问成员(成员变量、成员方法)满足:就近原则,先子类局部范围找 然后子类成员范围找 然后父类成员范围找,如果父类范围还没有找到则报错。
如果子父类中,出现了重名的成员,会优先使用子类的,此时如果一定要在子类中使用父类的怎么办? 可以通过super关键字,指定访问父类的成员。
五:方法重写
Java子类重写父类方法标识: @Override
重写方法的名称、形参列表必须与被重写方法的名称和参数列表一致。
私有方法不能被重写。
子类重写父类方法时,访问权限必须大于或者等于父类 (暂时了解 :缺省 < protected < public)
子类写一个与父类申明一样的方法覆盖父类的方法。 @Override注解可以校验重写是否正确,同时可读性好。
重写方法的名称和形参列表应该与被重写方法一致。 私有方法不能被重写。
重写父类的静态方法会报错的。
public class T06 {
public static void main(String[] args) {
person fu = new person();
student stu = new student();
fu.drink();
stu.drink();
}
}
/**
* 人类
*/
class person
{
public void drink()
{
System.out.println("父类喝水");
}
}
/**
* 学生类
*/
class student extends person
{
@Override
public void drink()
{
System.out.println("子类喝水");
}
}
输出:
父类喝水
子类喝水
六:this、super关键字
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
---|---|---|---|
this | this.成员变量 访问本类成员变量 | this.成员方法(…) 访问本类成员方法 | this(…) 访问本类构造方法 |
super | super.成员变量 访问父类成员变量 | super.成员方法(…) 访问父类成员方法 | super(…) 访问父类构造方法 |
我们先来看下方的代码:
package d0131;
public class T05 {
public static void main(String[] args) {
student stu = new student();
stu.drink();
}
}
/**
* 人类
*/
class person
{
public int i = 1;
public void drink()
{
System.out.println("父类喝水");
}
}
/**
* 学生类
*/
class student extends person
{
int i = 2;
@Override
public void drink()
{
int i = 3;
System.out.println(i);
System.out.println(i);
System.out.println(i);
}
}
控制台输出:
3
3
3
那现在有一个小要求,要求控制台输出3/2/1,我们该如何实现呢?
这其中就需要使用到this以及super关键字。
代码如下所示:
public class T05 {
public static void main(String[] args) {
student stu = new student();
stu.drink();
}
}
/**
* 人类
*/
class person
{
public int i = 1;
public void drink()
{
System.out.println("父类喝水");
}
}
/**
* 学生类
*/
class student extends person
{
int i = 2;
@Override
public void drink()
{
int i = 3;
System.out.println(i);
// 当前这个类的成员变量i
System.out.println(this.i);
// 父类的成员变量i
System.out.println(super.i);
}
}
输出:
3
2
1
七:构造函数
1:子类的构造函数中,默认都加载了一次父类的构造函数,也就是super()
public class T01 {
public static void main(String[] args) {
zi zi1 = new zi();
zi zi2 = new zi("xh");
}
}
class fu
{
public fu()
{
System.out.println("我被调用了!");
}
private String files;
public String getFiles() {
return files;
}
public void setFiles(String files) {
this.files = files;
}
}
class zi extends fu
{
/**
* 无参构造方法
*/
public zi()
{
// 默认就有一个super方法
// super();
}
/**
* 重载有参构造方法
* @param name
*/
public zi(String name)
{
// 默认就有一个super方法
// super();
}
}
上边的程序,控制台输出:
我被调用了!
我被调用了!
为什么会有这样的现象呢?
因为有继承,说明子类可以使用父类的成员变量,那也就意味着父类的成员变量一定要有一直才可以被使用,所以在创建类对象的时候,会调用子类的构造方法,而子类的构造方法中会先去调用父类的构造方法,目的就是给父类的额成员变量默认初始化
2:子类的所有构造方法中,第一行要么是super(参数),要么是this(参数),他们不可以共存。并且子类中所有的构造方法中至少有一个构造方法里边调用的是super(参数)
class zi extends fu
{
/**
* 无参构造方法
*/
public zi()
{
// 默认就有一个super方法
// super();
this("xxx");
}
/**
* 重载有参构造方法
* @param name
*/
public zi(String name)
{
// 默认就有一个super方法
// super();
this();
}
}
这样写是不行的。编译报错。死循环了属于是。
以上大概就是 java 继承的基本使用。
有好的建议,请在下方输入你的评论。