---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
今天学习了面向对象的第二大特征——继承,主要学习了继承的定义,继承的特点,继承中变量,构造方法,成员方法之间的关系,final关键字。
1:继承的定义:
把多个类中相同的属性或者行为提取出来,定义到一个类中,然后让这多个类和该类产生一种关系,使这多个类具有这个类的属性和行为,这种关系就是继承。
继承关系用关键字extends来产生,用于类与类之间,继承的好处是:提高了代码的复用性,同样的代码不用在每个类中重复的写;使类与类之间产生关系。
继承的格式:class 子类名 extends 父类名{
}
但是不能因为某一个方法 而去继承,这样的话,可能会的到一些不需要的方法。那么如何判断是否能够使用继承呢?例如有两个类,class A,classB,要使它们发生继承关系,就要先判断A是B的一种或者B是A的一种,否则就不能使用继承。
2:继承的特点:
A:java中只支持单继承,不支持多继承。也就是说一个子类只能有一个父类,不能有多个父类。
B:java中支持多层继承,也叫多重继承。就是一个子类可以通过继承父类而继承父类的父类。
3:继承之间成员变量的之间的关系:
A:如果子类和父类成员变量名不同,那么在程序中调用哪个变量就是哪个变量。
B:如果子类和父类成员变量名相同,在子类的方法中,使用一个变量的时候,先在局部变量中找,如果局部变量中找不到,再到子类的成员变量中找,如果还找不到,那么 就在父类的成员范围中找。一直找到集成体系的最上层,如果还找不到,那么编译就会报错。
如果有局部变量,成员变量,父类成员变量,而且这些变量名全部相同,直接调用的是局部变量,如果调用成员变量,用this.变量名,调用父类的成员变量,用super.关键字。
例如:
class Father {
int num = 10; //定义父类的成员变量
}
class Son extends Father { //定义子类继承父类
int num = 20; //定义子类的成员变量
public void show() {
int num = 30; //定义子类局部变量
System.out.println(num);
Systrm.out.println(this.num);
System.out.println(super.num);
}
}
class ExtendsDemo {
public static void main(String[] args) {
Son s = new Son();
s.show();
}
}
这就是对继承的子父类中同名的变量调用的例子代码,执行结果是:30,20,10.第一个输出中输出的输出的是子类成员变量的值,第二次输出中输出的值是子类成员变量的值,第三次调用的是父类成员变量的值。
4:继承中构造方法之间的关系:
初始化子类之前,先初始化父类的数据,因为在初始化子类的时候要用到父类的数据。
注意事项:
A:调用默认构造方法是默认调用的,这个时候父类并没有创建父类对象,仅仅是对父类的数据进行了了初始化
B:子类构造方法中,第一条默认语句是 super(), 表示调用的是父类的无参构造方法。
C:父类如果没有无参构造方法,用super(参数)调用父类带参数的构造方法或者用this()调用本类其他构造方法,但是最终还是要调用父类的构造方法。
D:构造方法中this(...)或者super(...)语句只能出现一个,并且只能放在第一条,避免多次对父类数据进行初始化。
例如:
class Person {
Person() {
System.out.println(“A”);
}
}
class Student extends Person {
Student()
{
System.out.println(“B”);
}
}
class personDemo
{
Public staticvoid main (String [] args)
{
Students = new Student();
}
}
这段代码的执行结果是:A,B,在初始化子类之前先访问父类的构造方法,父类的构造方法先执行。
5:继承中成员方法之间的关系:
继承中如果成员方法不同,那么子类就拥有父类中非静态的成员方法,如果子类中的成员方法和父类中的成员方法一模一样,就会出现覆盖操作,也就是重写。
重写的注意事项:
A:父类中的私有方法不能被重写
B:子类重写父类方法的权限要大于或等于父类的权限。
例如:
class Father {
private void show(){} //定义父类的私成员变量
}
class Son extends Father {
private void show() {}
}
class Test {
public static void main(String[] args) {
Son s = new Son();
s.show();
}
}
这个例子中的父类和子类中的成员方法就不是重写,编译会报错,因为父类的方法是私有的,不能被子类重写。
重写和重载的区别:
重载:在一个类中,方法名相同,参数列表不同,和返回值无关
重写:在子父类中,声明方式一模一样(方法名,参数列表,返回值类型)。
6:final关键字:
final关键字的意思是最终的,可以用来修饰类,成员方法,成员变量。
final的特点:
被final修饰的类不能被继承。
被final修饰的方法不能被重写。
被final修饰的变量是常量。
这些就是继承中的内容,继承是面向对象的第二特征,也是比较复杂的,这些不能强行去记忆,应该结合一些与之相关的例子程序来理解记忆。
下面的代码就是一个通过继承的方式写的小程序。
/*
狗类:
属性:姓名,年龄
行为:吃饭,跑步
猫类:
属性:姓名,年龄
行为:吃饭,捉迷藏
请自己设计出一个合理的方案,分析用几个类就可以把我的需求给描述出来。
*/
class Animal {
//成员变量
private String name;
private int age;
//空参数的构造方法
public Animal() {}
//带参数的构造方法
public Animal(String name,int age) {
this.name = name;
this.age = age;
}
//成员方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void eat() {
System.out.println("吃饭");
}
}
class Dog extends Animal { //定义Dog类继承Animal类
public Dog() {}
public Dog(String name,int age) {
super(name,age); //调用父类带参数的构造方法
}
//定义子类的成员方法
public void run() {
System.out.println("跑步");
}
}
class Cat extends Animal {
public Cat() {}
public Cat(String name,int age) {
super(name,age);
}
public void zhuoMiCang() {
System.out.println("捉迷藏");
}
}
class ExtendsDemo
{
public static void main(String[] args)
{
//通过无参构造方法+setXxx()给变量进行赋值
Dog d1 = new Dog();
d1.setName("dahuang");
d1.setAge(2);
System.out.println(d1.getName() + " Hello World! " + d1.getAge());
d1.run();
//通过带参构造方法对变量进行赋值
Cat c1 = new Cat("kitty",3);
System.out.println(c1.getName() + " Hello World! " + c1.getAge());
c1.zhuoMiCang();
}
}
----------------------<ahref="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<ahref="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
详细请查看:<a href="http://www.itheima.com"target="blank">www.itheima.com</a>