黑马程序员_继承

---------------------- <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>

 

转载于:https://my.oschina.net/u/1390204/blog/284626

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值