您的位置:首页 > 职场人生

黑马程序员--面向对象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关键字来调用父类中的变量,方法。

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中“万物皆对象”的理解有了一定的认识,在实际学习中一定要牢牢把握面向对象的思想,需要解决什么问题,我就找对应的对象,没有对象就自己创建。把需要的功能,属性,数据都封装进对象供我所用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: