黑马程序员——java基础--面向对象--继承
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
继承:
1.当一个类中包含了另一个类的所有变量个方法时,但另一个类中不包含另一个类的所有变量和方法时,表示范围比较小的就可以作为另一个的父类。
集合表示:A属于B,B不属于A,A就可以作为B的父类,B继承A
2.当只是为了获取其他类的功能的时候,不能为了简化代码而继承。
3.必须是类与类之间的所属关系才可以继承,所属关系看前面集合
继承的特点:
1.不支持多继承,只支持单继承:
多继承的话容易产生安全隐患:
class A{ Demo{ System.out.println("a"); } } class B{ Demo{ System.out.println("b"); } } class C extends A,B{ C c = new c(); c.Demo(); }
这时候C就会出现选择错误,不知道要调用A还是要调用B。
2.继承提高了代码的复用性
3.让类与类之间产生了关系,有了这关系,才有了多态的特性。
class person{ int age; String name; } class student extends person{ void study(){ System.out.println("good student"); } } class work extends person{ void work(){ System.out.println("good worker"); } } public class extendsDemo{ public static void main(String[] args){ student s = new student(); s.name = "Archer"; s.age = 21; System.out.println("age:"+age+"name:"+name); s.work(); work w = new work(); w.work(); } }java支持多层继承。也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。
那么在具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象,
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象使用功能。
子类与父类出现后,类中的成员都有哪些特点:
1.成员变量
当子父类中出现一样的属性时,子类类型的对象,调用该属性,值是子类的属性值
class student{ int num = 4; study(){ System.out.println("good study"); } show(){ System.out.println(num); } } class smallstudent extends student{ int num = 5; show(){ System.out.println(num); } } public class extendsDemo{ public static void main(String args[]){ new smallstudent().show();//输出的值为5,不是4 } }如果想要调用父类中的属性值,需要使用关键字super
this和super的区别:
this:代表是本类类型的对象引用
super:代表的是子类所属父类中的内存空间的引用
注意,字父类中通常不会出现同名的成员变量,因为父类中只要定义了,子类就不用再定义了,直接继承过来就可以了。
super关键字。
class student{ int num = 4; study(){ System.out.println("good study"); } show(){ System.out.println(num); } } class smallstudent extends student{ int num = 5; show(){ System.out.println(super.num);//输出的是父类的值,也就是4 } } public class extendsDemo{ public static void main(String args[]){ new smallstudent().show();//输出的值为4 } }
2.成员函数
当子父类中出现了一模一样的方法时,建立子类的对象会运行子类中的方法,好像父类中的方法都被覆盖掉一样,所以这种情况,是函数的另一个特性--覆盖(重写)
什么时候使用覆盖呢?
当一个类的功能需要修改时,可以通过覆盖来实现。
3.构造函数
发现子类构造函数运行时,先运行父类构造函数,为什么呢?
子类的所有构造函数中的第一行,其实都有一条隐身的语句super();
super():表示父类的构造函数,并会调用参数相对应的父类中的构造函数,而super():是在调用是在调用父类中的空参数构造函数。
为什么子类对象初始化时,都需要调用父类中的函数,也就是为什么子类构造函数的第一行要加入这个super()?
因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的,所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程。
class student{ student(){ System.out.println("student"); } } class smallstudent extends student{ smallstudent(){ System.out.println("smallstudent"); } } public class extendsDemo{ public static void main(String args[]){ smallstudent s = new smallstudent(); s.smallstudent();//输出是student // smallstudent } } 所以子类构造函数实例化的过程中是先访问父类的构造函数。 注意事项: class student{ student(){ System.out.println("student"); } student(int n){ System.out.println("4"); } } class smallstudent extends student{ smallstudent(){ //这里是super关键字 System.out.println("smallstudent"); } smallstudent(int m){ //这里可以是this关键字,也可以是super关键字 System.out.println("5"); } } public class extendsDemo{ public static void main(String args[]){ smallstudent s = new smallstudent(); s.smallstudent(); } } 但是如果父类没有空参数的构造函数,这样就需要给子类手动在第一行添加super();了。 class student{ student(int n){ System.out.println("4"); } } class smallstudent extends student{ smallstudent(){ super(3); System.out.println("smallstudent"); } smallstudent(int m){ super(4); System.out.println("5"); } } public class extendsDemo{ public static void main(String args[]){ smallstudent s = new smallstudent(); s.smallstudent(); } }
不然会报错,为什么必须是第一行呢,因为构造函数是为了初始化,如果放在后面的话,子类先初始化,父类再初始化,就会把子类的值给更改,所以初始化的动作要先完成。
在方法覆盖时,注意两点:
1子类覆盖父类时,必须保证,子类方法的权限必须大于等于父类方法权限实现继承,否则,编译失败。
2.覆盖时,要么都静态,要么都不静态,因为静态只能覆盖静态。
函数默认的权限是package,他是介于private和public之间的。
private、public、protected权限大小:
private:只能由1.该类中的函数、2.其友元函数访问。
不能被任何其他访问,该类的对象也不能访问。
protected:可以被1.该类中的函数、2.子类的函数、以及3.其友元函数访问。但不能被该类的对象访问。
public:可以被1.该类中的函数、2.子类的函数、3.其友元函数访问,也可以由4.该类的对象访问。
继承的一个弊端,打破了类的封装性,对于一些类,或者是类中的功能,是需要被继承的,或者是重写的,怎么解决呢?
用关键字:final
final的特点:
1.这个关键字是一个修饰符,可以修饰类,方法和变量
2.被final修饰的类是一个最终类,不可以被覆盖,不可以被继承
3.被final修饰的方法是一个最终的方法,不可以被覆盖
4.被final修饰的变量是一个常量,只能赋值一次
class student{ final showt(){ System.out.println("student"); }//这个方法在不可以被修改 } class smallstudent extends student{ smallstudent(){ System.out.println("smallstudent"); } } public class extendsDemo{ public static void main(String args[]){ final PI = 3.14; //这个和c语言中的define有点像,和const更相似 smallstudent s = new smallstudent(); s.smallstudent(); } } 抽象: 什么是抽象? 不具体,看不明白,抽象类表象体现 在不断抽取过程中,将共性内容中的方法申明抽取,但是方法是不一样的,没有抽取,这是抽取到的方法,并不是具体的,需要被指定关键字abstract所标示,申明为抽象方法。 抽象方法所在类一定要标示为抽象类,也就是说该类需要被abstract关键字所修饰 class student{ study(){ System.out.println("study"); } } class smallstudent extends student{ study(){ System.out.println("study english"); } } class bigstudent extends student{ study(){ System.out.println("study code"); } } ppublic class abstractDemo{ public static void main(String args[]){ } } 这时候smallstudent和bigstudent中都用到了study方法,但是功能里面具体的实现不一样,再继承student类就没有什么意义,这时候就需要使用抽象类。 abstract class student{ abstract study();//这时候就只有方法,却没有方法体 } class smallstudent extends student{ study(){ System.out.println("study english"); } } class bigstudent extends student{ study(){ System.out.println("study code"); } } ppublic class abstractDemo{ public static void main(String args[]){ } }如果抽象类中包含多个抽象方法,子类必须对全部的抽象方法初始化,否则会出错。
抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
abstract 关键字,和哪些关键字不能共存。
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
可是抽象方法运行没意义。
抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化
练习:员工有姓名,员工号,工资,经理也属于员工,但是他有奖金。
分析:
1.必须要有一个员工类
2.经理属于员工,但是不完全属于,他有自己的特殊属性。
3.员工类必须的属性:name/id/gongzi
4.经理附加属性:bonus
class Employee{ private String name; private String id; private int gongzi; // 初始化 Employee(String name, String id, int gongzi){ this.name = name; this.id = id; thi.gongzi = gongzi; } public abstract work();//没有方法体 } class Manage extends Employee{ private int bonus; Manage((String name, String id, int gongzi, int bonus){ super(name,id,gongzi); this.bonus = bonus; } public void work(){ System.ut.println("manage work"); }//区别 } class pro extends Employee{ pro((String name, String id, int gongzi){ super(name,id,gongzi); } public void work(){ System.ut.println("pro work"); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。