继承的概念
继承:一个类获得另一个类的属性及行为的过程,使用关键字extends;此时两个类之间就产生了关系。
继承的好处
1.提高了代码的复用性
2.使类与类之间产生了关系(被继承的类称为父类,继承的类称为子类)
继承的特点
java类与类之间是单继承的,但是其支持多继承:这就好像一个儿子只能有一个父亲,而一个父亲
可以有多个儿子一样
单继承:一个类只能有一个父类
多继承:一个类可以有多个父类
注意:什么时候继承?
当事物之间存在所属关系时,x 是 y 的一种
举例:如下面的例子中,学生、工人都是人,所以学生类和工人类可以继承人类;亦即学生和工人的
父类是人。
class Person
{
int age;
String name;
public void eat()
{
System.out.print("吃饭");
}
}
class Student extends Person//Student类继承了Person类:继承Person类中定义的所有属性和方法
{
public void study()
{
System.out.print("学习"+",");
}
}
class Worker extends Person//work类继承了Person类:继承了Person中定义的所有属性和方法
{
public void work()
{
System.out.print("工作"+",");
}
}
/*Worker 和Student是子类;Person是父类。java是单继承 多继承会导致调用的不确定性*/
class Demo1
{
public static void main(String[] args)
{
Student stu1=new Student();
stu1.age=24;
stu1.name="Tom";
System.out.print(stu1.age+","+stu1.name+",");
stu1.study();
stu1.eat();
System.out.println();
Worker k1=new Worker();
k1.age=35;
k1.name="Jim";
System.out.print(k1.age+","+k1.name+",");
k1.work();
k1.eat();
}
}
继承中成员变量的特点
当存在继承关系
(1).子类中的成员变量和父类中的成员变量不同时则在输出成员变量时各自输出各自的
(2).当子类中出现和父类同名的成员变量时的输出:"就近原则" 即输出的是子类的成员变量
比如下边的例子:
class Fu//定义了一个Fu类:这是父类
{
int num1=5;//定义父类属性num1
}
class Zi extends Fu//定义了一个Zi类继承Fu类:Zi是子类
{
static int num1=6;//定义子类属性num1
public void show()//定义子类show方法
{
System.out.println(num1);
}
}
class Demo2
{
public static void main(String[] args)//main函数:程序运行的入口
{
Zi z=new Zi();//创建子类对象
z.show();//通过子类对象访问成员函数show()
}
}
分析:语句System.out.println(num1); 相当于语句 System.out.println(this.num1);
即系统默认给num1的前面加上了this. this表示指向当前对象(或者说本类对象)的引用
那么如果想要同时输出父类中的num1和子类中num1时,应该怎么办呢?
这是引入了关键字 super
class Fu//定义了一个Fu类:这是父类
{
int num1=5;//定义父类属性num1
}
class Zi extends Fu//定义了一个Zi类继承Fu类:Zi是子类
{
static int num1=6;//定义子类属性num1
public void show()//定义子类show方法
{
System.out.println(this.num1+","+super.num1);
}
}
class Demo3
{
public static void main(String[] args)//main函数:程序运行的入口
{
Zi z=new Zi();//创建子类对象
z.show();//通过子类对象访问成员函数show()
}
}
小结:(1).this:是一个引用,总是指向当前对象
(2).super:不是引用,当子父类中出现同名成员时,用于区分子父类对象。
super 超级的 用来调用父类的成员
继承中重写的概念
重写(覆盖):子类在继承父类时,含有和父类一样的函数;但当创建子类对象时,通过对象调用
的是重写之后的方法。这里的"一样"包括:函数名相同、并且返回值类型相同;但不过
与参数列表无关。
注意:(1).子类在重写父类时,权限要大于父类中方法的权限
(2).父类中私有的方法不能被重写
(3).静态只能覆盖静态
(4).当父类中的方法返回值是引用类型时,子类在重写时的返回值可以是父类中的返回值类型,
也可以是其子类类型。
方法(函数)的重写案例:
class Fu//定义了一个Fu类:这是父类
{
public void eat()//定义了一个eat的方法
{
System.out.println("细嚼慢咽的吃");//输出"细嚼慢咽的吃"
}
}
class Zi extends Fu//定义了一个Zi类并继承Zi类:这是子类
{
public void eat()//重写
{
super.eat();//沿用父类的eat方法
System.out.println("吃完抽根烟然后去散步");//子类与父类不同之处
}
}
class Demo4
{
public static void main(String[] args)//main函数:程序运行的入口
{
Zi zi=new Zi();//创建了一个子类对象zi
zi.eat();//通过子类对象zi调用eat函数
}
}
由此可见重写的好处:
提高代码的扩展性:当子类需要父类的功能时可以沿用,在子类的重写的方法
的方法体语句的第一行加上语句:super.方法名(); 即可 子类自己还可以定义自
身的特有内容。
继承中构造函数的特点
在继承中,当创建子类对象的时候,先调用父类的无参构造方法,再调用子类的构造方法:
原因是在运行程序时JVM会在子类的构造方法的第一行加上一条语句: super(); 默认调用的是
父类中的无参构造方法(如下面的例1)。
注意:当父类中不存在无参的构造方法或是在类想调用父类的带参数的构造方法时,由于JVM
不会再为子类的构造函数内添加语句super(); 故必须在第一行手动加上语句super语句:
super(参数1,参数2...); 如下面的例2.
例1:
class Fu//定义了一个Fu类:这是父类
{
Fu()//父类的无参构造函数
{
System.out.println("I miss you");//输出"I miss you"
}
}
class Zi extends Fu//定义了一个Zi类继承了Ful类:这是子类
{
Zi()//子类的无参构造函数
{
System.out.println("What are you doing now?");//输出"What are you doing now?"
}
}
class Demo5
{
public static void main(String[] args)//main函数:程序运行的入口
{
Zi z=new Zi();//创建子类对象
}
}
例2:
class Fu//定义了一个Fu类:这是父类
{
int age;//定义对象属性
String name;
Fu()
{
System.out.println(666);
}
Fu(int age,String name)//父类中的带参构造函数
{
this.age=age;
this.name=name;
}
}
class Zi extends Fu//定义了一个Zi类继承了Fu类:这是子类
{
Zi(int age,String name)//子类中带参构造方法
{
super(age,name);//调用父类中的带参构造方法
System.out.println("How are you?");//输出"How are you?"
}
}
class Demo6
{
public static void main(String[] args)//main函数:程序运行的入口
{
Zi z=new Zi(25,"李四");//创建子类对象
System.out.println(z.age+","+z.name);//输出年龄和名字
}
}