黑马程序员--面向对象02
2015-07-25 00:49
453 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
注:视频来源,毕向东老师的 JAVA 基础视频。
1)继承的好处
1、提高代码的复用性。
2、让类与类之间产生了关系。有了这个关系才有了多态性。
3、java 支持多实现。
2)继承的原则:
java 语言中,java 只支持单继承,不支持多继承。因为多继承容易带来安全隐患,当多个父类中定义了相同方法时,当功能不同,不确定要运行A还是B,但是java保留了这种机制,java用另一种体现机制来完成表示。叫多实现。
3)继承的扩展:子父类关系
子父类中的函数。当子类中出现和父类一模一样的函数时候,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况也是函数的另一个特性:重写(覆盖)。
4)父类,一般称为基类。子父类出现后,出现新特性:
重载:只看同名参数列表。
重写:子父类方法要一模一样。
子类重写父类中的方法,但是不继承父类方法中的内容,只执行自己重写方法中的内容子类中用super关键字来调用父类中的变量,方法。
打印结果:
hahaha
4
2) 抽象类:当一个类被声明为abstract时,这个类被称为抽象类。所谓的抽象类就是没有实例对象的类。
3) 抽象方法:作为修饰符,abstract声明了一种没有具体对象的,出于组织概念的层次关系需要而存在的抽象类;作为类方法修饰符,abstract则声明了一种仅有方法头,而没有具体的方法体和操作实现的抽象方法。
4)抽象类的特点:
1、抽象类和抽象方法必须用abstract关键字来修饰。
2、抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符abstract返回值类型 函数名(参数列表);
3、 抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
而且抽象类即使创建了对象,调用抽象方法也没有意义。
5) 个人理解:当父类中的一个方法,无法确定其具体的实现形式,那么就要用到抽象方法。而这些不去实现抽象方法的类就是抽象类。
注:被abstract修饰的函数不能同时被private、final、static修饰。
原因:
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private:抽象类中的私有的抽象方法,不被子类所知,就无法被复写。 而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。
2) 初期理解:可以理解为一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表现。
3)定义接口时的格式特点:
1、接口中常见定义:常量,抽象方法。
2、接口中的成员都有固定的修饰符。
常量:public static final
方法:public abstract
4) 深入理解:接口是不可以创建对象的,因为有抽象方法。需要被子类实现,而子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。接口可以被类多实现,也是对多继承不支持的转换形式。Java 支持多实现。
5)接口的特点:
1、接口是对外暴露的规则。
2、接口是程序的功能扩展。
3、接口的出现降低耦合性。
4、接口可以用来多实现。这也是对多继承不支持的转换形式。java支持多实现。
5、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
6、 接口与接口之间可以有继承关系。而且可以多继承。
1)多态的体现
1、父类的引用指向了自己子类的对象。
2、父类的引用也可以接收自己的子类对象。
2)多态的好处
提高了程序的扩展性,前期定义的代码可以使用后期的内容。
3)多态的前提
1、类与类之间必须有关系,要么继承,要么实现。
2、存在覆盖。父类中有方法被子类重写。
4)多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5)多态的特点
1、多态中非静态成员函数的特点
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。这就是说,如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
2、多态中成员变量的特点
无论编译和运行,都参考左边(引用变量所属的类)。
3、多态中静态成员函数的特点
无论编译和运行,都参考左边。
1、内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this。
2、外部类要访问内部类,必须建立内部类对象。
二、访问格式
1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。
格式:
外部类名.内部类名 变量名 =外部类对象.内部类对象;
如: Outer.Inner in =new Outer().new Inner();
当内部类在外部类中的成员位置上时,可以被成员修饰符所修饰。比如:
private:将内部类在外部类中进行封装。
static:内部类就局部static的特性。但是当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,直接访问static内部类的非静态成员的格式为:
new 外部类名.内部类名().方法名();
如:new Outer.Inner().function();
在外部其他类中,直接访问static内部类的静态成员格式为:
外部类名.内部类名.方法名();
如:Outer.Inner.function();
注意:
1)当内部类中定义了静态成员时,该内部类必须是static的。
2)当外部类中的静态方法访问内部类时,内部类也必须是static的。
3)在实际应用中,内部类通常被定义为private,而很少定义为public。
2、内部类定义在局部
内部类定义在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。
1)不可以被成员修饰符修饰。如public、private、static等修饰符修饰。它的作用域被限定在了声明这个局部类的代码块中
2)可以直接访问外部类中的成员,因为还持有外部类中的引用。
注意:内部类不可以访问它所在的局部中非最终变量。只能访问被final修饰的局部变量。
三、匿名内部类
1、匿名内部类其实就是内部类的简写格式。
2、定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
特殊情况:因为所以的类都有一个父类Object,所以在定义时也可以用Object。
3、匿名内部类的格式: new父类或者接口(){定义子类的内容}
4、其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
5、匿名内部类中定义的方法最好不要超过3个。
匿名内部类的利与弊:
好处:简化书写
弊端:1、不能直接调用自己的特有方法、
2、不能做强转动作。
3、如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。所以匿名内部类中定义的方法有一般不超过3个。
什么时候用?当函数参数列表传入的是接口类型对象时。
1)异常:就是程序在运行时出现的不正常情况。
2)异常由来:java 对不正常情况进行描述后的对象体现。
对于问题的划分两种:
一种是:严重的问题,对于严重的问题,java 通过 error 类进行描述。
一种是:非严重的问题。对于非严重的问题,java 通过 Exception 类进行描述。
3)对于Exception 可以使用针对性的处理方式进行处理。
String getMessage();获取异常信息。
Throwable
二、异常在子父类覆盖中的体现
1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2)如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集。
3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,就必须要进行 try 处理。绝对不能抛出。
三、异常的自定义
1)描述:因为项目中会出现一些特有的问题,而这些问题并未被 java 所描述并封装对象。所以对于这些特有的问题可以按照 java 的对问题的封装思想。将这些特有的问题,进行自定义异常封装。
2)需求:在程序中,对除数是负数也视为是错误的,那么该程序是无法继续进行运算的。
3)自定义的异常类:自定义异常必须是自定义类继承 Exception。
4)throws 和 throw 的区别。
throws 使用在函数上。
throw使用在函数内。
throws后面跟这是异常类,可以有多个异常类,用逗号隔开。
throw 后面跟着是异常对象。
5)当函数内容有 throw 抛出异常对象,并未进行 try 处理。必须在函数上声明,否则编译失败。
如果函数上声明了,那么函数内就不需要抛出了。
6)Exception 中有一个特殊的子类异常:RuntimeException
1、如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。
2、如果在函数上声明了该异常,调用者不用处理,编译一样通过。
3、之所以不用在函数中声明,是因为不需要让调用者处理。
当该异常发生,希望终止程序。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
7)对于异常的重分类理解:
1、编译时:被检测的异常。
2、编译时:不被检测的异常。(运行时异常,RuntimeException 以及其子类。)
8)异常体系的特点:
1、异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被 throws 和 throw 关键字所操作。只有异常体系具备这个特点。
2、finally:当执行了System.exit(0);后,系统 JVM 退出。finally不会被执行。
小结
异常就是讲问题进行封装,将正常流程代码和问题处理代码相分离,方便于阅读。
总结:
到这里,面向对象的学习已经基本完成。对于java中“万物皆对象”的理解有了一定的认识,在实际学习中一定要牢牢把握面向对象的思想,需要解决什么问题,我就找对应的对象,没有对象就自己创建。把需要的功能,属性,数据都封装进对象供我所用。
注:视频来源,毕向东老师的 JAVA 基础视频。
继承
新的实例要在原有类上的扩展,就是继承原有类的功能外还可以扩展需要的功能。1)继承的好处
1、提高代码的复用性。
2、让类与类之间产生了关系。有了这个关系才有了多态性。
3、java 支持多实现。
2)继承的原则:
java 语言中,java 只支持单继承,不支持多继承。因为多继承容易带来安全隐患,当多个父类中定义了相同方法时,当功能不同,不确定要运行A还是B,但是java保留了这种机制,java用另一种体现机制来完成表示。叫多实现。
3)继承的扩展:子父类关系
子父类中的函数。当子类中出现和父类一模一样的函数时候,当子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。这种情况也是函数的另一个特性:重写(覆盖)。
4)父类,一般称为基类。子父类出现后,出现新特性:
重载:只看同名参数列表。
重写:子父类方法要一模一样。
子类重写父类中的方法,但是不继承父类方法中的内容,只执行自己重写方法中的内容子类中用super关键字来调用父类中的变量,方法。
package fuxi; /** * *@author XiaLei */ public class Day7Test1 { public static void main(String[] args) { Zi z =new Zi(44); } } class Fu{ int num = 4; Fu(){ System.out.println("hahaha"); } public void speak(){ System.out.println("woshinidie"); } } class Zi extends Fu{ int num = 5; Zi(){ super();//调用父类构造函数。 } Zi(int num){ this();//调用本类构造函数。 num = super.num;//用父类的成员变量给子类对象赋值。父类不要私有。 System.out.println(num); } public void speak(){//覆盖父类方法,但是内容不同。 System.out.println("woshinierzi"); } }
打印结果:
hahaha
4
抽象类与抽象方法
1) 概念:在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。2) 抽象类:当一个类被声明为abstract时,这个类被称为抽象类。所谓的抽象类就是没有实例对象的类。
3) 抽象方法:作为修饰符,abstract声明了一种没有具体对象的,出于组织概念的层次关系需要而存在的抽象类;作为类方法修饰符,abstract则声明了一种仅有方法头,而没有具体的方法体和操作实现的抽象方法。
4)抽象类的特点:
1、抽象类和抽象方法必须用abstract关键字来修饰。
2、抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符abstract返回值类型 函数名(参数列表);
3、 抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
而且抽象类即使创建了对象,调用抽象方法也没有意义。
5) 个人理解:当父类中的一个方法,无法确定其具体的实现形式,那么就要用到抽象方法。而这些不去实现抽象方法的类就是抽象类。
注:被abstract修饰的函数不能同时被private、final、static修饰。
原因:
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private:抽象类中的私有的抽象方法,不被子类所知,就无法被复写。 而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。
package fuxi; /** * 题目:员工有姓名,工号,工资属性,有工作方法,经理比员工多一个奖金属性。 * 思路:工作方法具体方式不知道,定义为抽象方法。 *@author XiaLei */ public class Day7Test { public static void main(String[] args) { } } abstract class Stuff{ private String name; private int id; private int num; Stuff(String name,int id,int num){ this.name=name; this.id = id; this.num = num; } public int setNum(int num){ return num; } public abstract void work();//具体工作是什么不知道,所以定义为抽象方法。这里注意抽象方法的书写格式。 } class JinLi extends Stuff{ private int money; JinLi(String name, int id, int num,int money) { super(name, id, num);//调用父类构造函数 this.money=money; } public void work(){//覆盖抽象方法。 System.out.println("jinliwork"); } public int giveMoney(int money){ this.money = money; return money; } }
接口
1) 概念:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。2) 初期理解:可以理解为一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表现。
3)定义接口时的格式特点:
1、接口中常见定义:常量,抽象方法。
2、接口中的成员都有固定的修饰符。
常量:public static final
方法:public abstract
4) 深入理解:接口是不可以创建对象的,因为有抽象方法。需要被子类实现,而子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。接口可以被类多实现,也是对多继承不支持的转换形式。Java 支持多实现。
5)接口的特点:
1、接口是对外暴露的规则。
2、接口是程序的功能扩展。
3、接口的出现降低耦合性。
4、接口可以用来多实现。这也是对多继承不支持的转换形式。java支持多实现。
5、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
6、 接口与接口之间可以有继承关系。而且可以多继承。
多态
多态可以理解为事物存在的多种体现形态。1)多态的体现
1、父类的引用指向了自己子类的对象。
2、父类的引用也可以接收自己的子类对象。
2)多态的好处
提高了程序的扩展性,前期定义的代码可以使用后期的内容。
3)多态的前提
1、类与类之间必须有关系,要么继承,要么实现。
2、存在覆盖。父类中有方法被子类重写。
4)多态的弊端
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5)多态的特点
1、多态中非静态成员函数的特点
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。这就是说,如果父类中有一个非抽象的方法,而子类继承后又将其复写了,在多态运行时,父类的引用调用这个同名函数时,被运行的将是父类中的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
2、多态中成员变量的特点
无论编译和运行,都参考左边(引用变量所属的类)。
3、多态中静态成员函数的特点
无论编译和运行,都参考左边。
package fuxi; /** * 需求: * 电脑运行实例 * 电脑运行基于主板 *@author XiaLei */ public class Day8Test1 { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); mb.usePCI(new NetCard()); } } interface PCI{ public void open(); public void close(); } class MainBoard{ public void run(){ System.out.println("main board run"); } public void usePCI(PCI pci){ if(pci!=null){ pci.open(); pci.close(); } } } class NetCard implements PCI{ public void open(){ System.out.println("netcard open"); } public void close(){ System.out.println("netcard close"); } }
内部类
一、内部类的访问规则1、内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this。
2、外部类要访问内部类,必须建立内部类对象。
二、访问格式
1、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。
格式:
外部类名.内部类名 变量名 =外部类对象.内部类对象;
如: Outer.Inner in =new Outer().new Inner();
当内部类在外部类中的成员位置上时,可以被成员修饰符所修饰。比如:
private:将内部类在外部类中进行封装。
static:内部类就局部static的特性。但是当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,直接访问static内部类的非静态成员的格式为:
new 外部类名.内部类名().方法名();
如:new Outer.Inner().function();
在外部其他类中,直接访问static内部类的静态成员格式为:
外部类名.内部类名.方法名();
如:Outer.Inner.function();
注意:
1)当内部类中定义了静态成员时,该内部类必须是static的。
2)当外部类中的静态方法访问内部类时,内部类也必须是static的。
3)在实际应用中,内部类通常被定义为private,而很少定义为public。
2、内部类定义在局部
内部类定义在外部类中的某个方法中,创建了这个类型的对象时,且仅使用了一次,那么可在这个方法中定义局部类。
1)不可以被成员修饰符修饰。如public、private、static等修饰符修饰。它的作用域被限定在了声明这个局部类的代码块中
2)可以直接访问外部类中的成员,因为还持有外部类中的引用。
注意:内部类不可以访问它所在的局部中非最终变量。只能访问被final修饰的局部变量。
三、匿名内部类
1、匿名内部类其实就是内部类的简写格式。
2、定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
特殊情况:因为所以的类都有一个父类Object,所以在定义时也可以用Object。
3、匿名内部类的格式: new父类或者接口(){定义子类的内容}
4、其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
5、匿名内部类中定义的方法最好不要超过3个。
匿名内部类的利与弊:
好处:简化书写
弊端:1、不能直接调用自己的特有方法、
2、不能做强转动作。
3、如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。所以匿名内部类中定义的方法有一般不超过3个。
什么时候用?当函数参数列表传入的是接口类型对象时。
异常
一、概论1)异常:就是程序在运行时出现的不正常情况。
2)异常由来:java 对不正常情况进行描述后的对象体现。
对于问题的划分两种:
一种是:严重的问题,对于严重的问题,java 通过 error 类进行描述。
一种是:非严重的问题。对于非严重的问题,java 通过 Exception 类进行描述。
3)对于Exception 可以使用针对性的处理方式进行处理。
String getMessage();获取异常信息。
Throwable
|--Error |--Exception
二、异常在子父类覆盖中的体现
1)子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2)如果父类方法抛出多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集。
3)如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,就必须要进行 try 处理。绝对不能抛出。
三、异常的自定义
1)描述:因为项目中会出现一些特有的问题,而这些问题并未被 java 所描述并封装对象。所以对于这些特有的问题可以按照 java 的对问题的封装思想。将这些特有的问题,进行自定义异常封装。
2)需求:在程序中,对除数是负数也视为是错误的,那么该程序是无法继续进行运算的。
class FuShuException extends Exception//将负数异常封装,体现了封装思想。 { private int value; FuShuException(String msg,int value) { super(msg); this.value=value; } public int getValue() { return value; } } class Demo { int div(int a,int b)throws FuShuException //构造代码块中抛出了出现了这边必须声明 { if(b<0) throw new FuShuException("出现了除数是负数的情况",b); return a/b; } } class ExceptionTest { public static void main(String[] args) { Demo d=new Demo(); try { int x=d.div(5,-1);//调用的方法中抛出了,这里必须try System.out.println("x="+x); } catch (FuShuException e) { System.out.println(e.toString()); System.out.println("出现负数的负数是:"+e.getValue()); } System.out.println("over"); } }
3)自定义的异常类:自定义异常必须是自定义类继承 Exception。
4)throws 和 throw 的区别。
throws 使用在函数上。
throw使用在函数内。
throws后面跟这是异常类,可以有多个异常类,用逗号隔开。
throw 后面跟着是异常对象。
5)当函数内容有 throw 抛出异常对象,并未进行 try 处理。必须在函数上声明,否则编译失败。
如果函数上声明了,那么函数内就不需要抛出了。
6)Exception 中有一个特殊的子类异常:RuntimeException
1、如果在函数内抛出该异常,函数上可以不用声明,编译一样通过。
2、如果在函数上声明了该异常,调用者不用处理,编译一样通过。
3、之所以不用在函数中声明,是因为不需要让调用者处理。
当该异常发生,希望终止程序。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
7)对于异常的重分类理解:
1、编译时:被检测的异常。
2、编译时:不被检测的异常。(运行时异常,RuntimeException 以及其子类。)
8)异常体系的特点:
1、异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被 throws 和 throw 关键字所操作。只有异常体系具备这个特点。
2、finally:当执行了System.exit(0);后,系统 JVM 退出。finally不会被执行。
小结
异常就是讲问题进行封装,将正常流程代码和问题处理代码相分离,方便于阅读。
总结:
到这里,面向对象的学习已经基本完成。对于java中“万物皆对象”的理解有了一定的认识,在实际学习中一定要牢牢把握面向对象的思想,需要解决什么问题,我就找对应的对象,没有对象就自己创建。把需要的功能,属性,数据都封装进对象供我所用。
相关文章推荐
- 【面试加分项】java自定义注解之申明注解
- 第一次使用拉勾网求职经历
- 全面解析《嵌入式程序员应该知道的16个问题》
- 出来行迟早是要还的(篇四):游戏开发离职日志和面试日志
- 程序员技术练级攻略(转)
- 黑马程序员--面向对象01
- 黑马程序员——Java基础-多态
- 黑马程序员——Java基础---常见对象1
- 【分享】2015 iOS工程师面试题
- 黑马程序员——Java基础---面向对象3
- 黑马程序员——Java基础---面向对象2
- 黑马程序员--集合框架
- 开启博客
- 今天遇到的3到智力面试题(给工人分金条,小鸟来回在2火车之间飞行的距离,精确称水问题)
- 阿里巴巴校招面试题目集锦
- 职业规划
- 黑马程序员——第八篇_内部类
- 黑马程序员——第七篇_高新技术
- 阿里一面(电话面试)
- IT人职业规划(绝对给力)