接口、多态、内部类、异常

接口:

当一个抽象类中全部是抽象方法的时候,这时,可以将这个抽象类定义成接口。

接口是一个特殊的抽象类。初期的一种简单理解。意味着接口中的方法都是抽象方法。

接口定义的格式:

interface 接口名{接口内容}

接口中的成员。都有固定修饰符。

    常见:

       1,常量。全局常量 有固定修饰符 public static final

       2,抽象方法。固定修饰符public abstract

       public static final int num=3;//=int num;

       public abstract void show();//= void show();

接口定义特点:

1, 接口用interface来定义

2, 接口中的成员都有固定的修饰符。

3, 接口不能被实例化

4, 接口必须由其子类覆盖了所有的抽象发方法后,盖子类才可以实例化。否则该子类还是一个抽象类。

5, 接口中的成员都是public修饰的

接口的出现好处:

    接口可以被多实现。是多继承在java种改良后的结果。

    一个类可以实现多个接口。

误区:

     记住:抽象函数,也要遵从函数的基本定义格式,要明确结果,要明确未知内容,只不过函数体由子类来完成。

一个类咋继承了一个类的同时还可以定义多个接口,接口的出现避免了单继承的局限新

class A

{

  public void show(){}

}

interface B

{

 public void show();

}

class C extends A implements B

{

  //这里可以什么都不写,因为C先继承了A,它里面就有show()方法,可以用此来实

//现接口B中的show();

}

**类与类之间是继承关系,而且是单继承。

**类与接口之间是实现关系,而且可以多实现

**接口与接口之间是继承关系,而且可以多继承。

InterfaceDemoA

{

   void showA();

}

InterfaceDemoB

{

   void showB();

}

InterfaceDemoC extends DemoB,DemoA

{

   void showC();

}

classDemoD implements DemoC

{

   public void showA();

   public void showB();

   public void showC();

}

接口的特点

1,  接口是对外暴露的规则

2,  接口是程序的功能扩展

3,  接口的出现降低了耦合性

4,  接口可以用来多实现

接口和抽象类的区别:

1, 类是用来继承的,只能单继承

接口是用来实现的,可以多实现

2, 类中可以定义非抽象内容,直接提供给子类使用

接口中只能定义抽象方法,需要子类全部实现

3, 类存在着继承关系,是is a关系

接口的实现关系,是like a 关系

共同点:它们都是不断抽取而来的

没有抽象方法的抽象类

    可以方便创建接口对象,去覆盖指定功能。

    interface Inter

{

       abstractvoid show1();

       abstractvoid show2();

       abstractvoid show3();

       abstractvoid show4();

}

abstract Test implements Inter

{

       publicvoid show1(){}

       publicvoid show2(){}

       publicvoid show3(){}

       publicvoid show4(){}  

}

class Test1 extends Test

{

       publicvoid show1()

       {

              System.out.println("show1run");

       }

}

class Test2 extends Test

{

       publicvoid show2()

       {

              System.out.println("show2run");

       }

}

多态:

在程序中的体现就是父类或者接口的引用只想自己的子类对象、

好处:提高代码的扩展性

弊端:前期建立父类的引用虽然可以接收后期所有该类的子类对象。但是只能使用父类中的功能,不能使用子类中的特有功能,因为前期的程序无法知道后期的子类特有的内容

      但是前期的程序可以使用自雷覆盖了父类的方法的内容

前提:

1,  必须存在着继承关系

2,  通常要有覆盖操作

多态的出现在成员调用上的特点:

1,  成员变量

      编译时期:参考的是引用型变量所属的类中是否有调用的成员变量,如果有,编译通过,如果没有编译失败

      运行时期:调用的也是引用型变量所属类中的成员变量。

      简单说:编译和运行都看等号的左边。

2,  成员函数

      编译时期:参考的是引用型变量所属的类中是否有调用的方法。有,编译通过,没有编译失败。

      运行时期:参考的是对象所属的类中是否有调用的方法,如果有运行子类自己的方法,如果没有就父类的方法

      简单说:编译时期看左边,运行时期看右边。

      因为函数有一个覆盖的特性

 

      非静态方法需要和当期运行的对象进行动态绑定,哪个对象调用了这个方法,这个方法就所属于哪个对象。就会运行哪个对象中的方法

3,  静态函数

      编译时期:参考的是引用型变量所属的类中的该方法。

      运行时期:参考的也是引用型变量所属的类中的方法。

      简单说:编译和运行都看左边

      因为静态方法是不所属于对象的,是所属于类的,它会在类加载的时候,静态绑定到所属的类上

父类引用指向子类对象

a引用可以指向Animal类中的方法。

Animal a=newDog();//子类对象的类型提升。向上转型。

a.eat();

好处:提高了扩展性  局限:只能使用父类中的方法。

这种提升可以限制对子类对象的操作。

 

Dog d=(Dog)a;//向下转型,转成子类型

d.eat();

d.lookHome();

可以使用子类的特有方法。

弊端,如果类型转换错误,会出现运行异常。

什么时候使用向上转型,和向下转型?

* 当需要对程序进行扩展,或者限定对对象的方法操作时,使用向上转型。操作其父类型

* 当要使用子类的特有的内容时,就需要向下转型。转型前一定要判断,否则容易出现问题。

注意:在这个转型过程中,自始至终都是一个子类对象在做着类型的变化而已。千万别把父类对象转成子类型。那是不可能。

在进行子类特有方法使用时,要进行向下转型,转型前一定要做判断。否则容易发生

ClassCastException

判断引用类型,要使用一个关键字完成。关键字:instanceof

对象 instanceof 类型

这个判断是向下转型的健壮性判断

Object:

所有类型的父类。

      所有对象都具备的内容不断的抽取,就到了一个顶层Object类中

  ----equals方法

  其他某个对象是否与此对象相等,底层实在比较内存地址是否相同

class Person extends Object

{

 Private int age;

 Person(int age)

  {

     this.age=age;

  }

//父类中已经提供了对象相等的比较,可以直接使用,如果比较内容不是所需要,可以将其覆盖,保留对其功能声明,定义自己所需的比较内容。

通常开发时,每一个对象都具备该方法,但是每个对象都具有自己的属性的比较方式。

所以都会覆盖方法建立每个对象自己特定的判断相同的依据。

  publicboolean equals(Object obj)//Object obj=p2;Object obj=new Person(14);

  {//只要年龄相同,就是同龄人,就是相同对象

  //既然要用到对象的特有内容。先下转型。

      if(!(obj instanceof Person))

        return false;

      Person p=(Person)obj;

      return this.age==p.age;

  }

}

class ObjectDemo

{

         public static void main(String[] args)

         {

             Persond1=new Person();

             Persond2=new Person();

             booleanb=d1.equals(d2);

             System.out.println("b="+b);

         }

}

      ----toString()       返回对象的字符串表达式

       如果输出语句中直接输出一个引用型变量,它会自动调用该对象toString变成字  符串打印

       为了让自定义的对象对应的字符串表现形式有意义,可以覆盖toString方法


内部类

特点:内部类可以直接访问外部类中的成员

     外部类要访问内部类中的成员,必须要创建内部类的对象。

当内部类编译后,其class文件是有所属关系的

Outer$Inner.class

class Outer

{

       classInner

       {

              publicvoid method()

              {

                     System.out.println("methodrun="+num);

              }

       }

       intnum=7;

       publicvoid show()

       {

              Innerin=new Inner();

       in.method();

       }

}

为什么要定义内部类?

类是用于描述事物的,而事物中如果还有具体的事物,而且这个内部的事物在访问着所属事物中的内容,这时这个内部的事物,也需要用到类来描述。这个类就是内部类。

为什么内部类可以直接访问外部类中的成员呢?

因为内部类都持有一个外部类的引用。外部类名.this

内部类的修饰符

当内部类定义在外部类的成员位置上时,可以使用成员的修饰符来进行内部类的修饰

1,  权限修饰符

      默认或者公有

      可以直接这样访问内部类

      外部类名.内部类名变量名=new 外部类对象.new 内部类对象;

      Outer.Inner in = new Outer().new Inner();

      私有:是不可以直接在外部访问。

2,static修饰符

    内部类被静态修饰,出现访问局限性,只能访问外部类中的静态成员

    内部类被静态后,会随着外部类的加载而加载。

    如果内部类中定义了静态成员,该内部类必须被静态修饰

    访问静态内部类中的非静态成员。直接穿件内部类对象。

    外部类名.内部类名 变量名=new 外部类名.内部类名

    Outer.Inner in=new Outer.Inner();

    访问静态内部类中的静态成员。不需要对象。

    外部类名.内部类名.内部类的静态成员

    Outer.Inner.function();

  记住:内部类只有定义在外部类的成员位置上,才具备这些修饰符、

匿名内部类

    凡是匿名都是简写格式

    要定义匿名内部类,必须要前提

    前提:内部类需要继承或者实现一个外部的类或者接口,这时才能简写成匿名内部类的形式

    匿名内部类其实就是一个匿名子类对象。这个对象用{}结尾部定义了成员。也就是说是

一个带有成员内容的对象,这个对象有点胖。

格式:new 父类名或接口名().成员。

abstract classDemo

{

   abstract void show();

}

class Outer

{

  private int num=5;

  public void method()

  {

    Demo d=new Demo()

{

  void show()

  {

    System.out.println(“show run…….”+num);

}

};

d.show();

}

}

   匿名内部类使用场景之一:

   当接口类型参数,该接口中方法不超过3个,可以使用匿名内部类作为函数的参数进行传递,这样简化了书写。但是接口方法较多时,不要使用匿名内部类,影响阅读性。

异常

   在运行时期发生的一些不正常情况。

   异常的由来:程序运行时总会有些不正常的情况。Java语言对这些不正常情况也进行了描述。并对这些不正常进行了对象的封装。是描述不正常情况的对象

   异常体系:

   Throwable:可抛出

        |——Error:严重问题。一般都是jvm从底层抛出来的问题,通常不需处理。

        |——Exception:可以定义针对性的处理方式对该种情况进行处理

    不正常情况分为两种:一种是可以解决的Exception,一种是严重性的Error

    无论是Error还是Exception,它们的子类都有一个特点:子类名称的后缀都是父类名

   这个异常体系最大的特点:就在于体系中的类和对象都具备可抛性。可抛性的体现就是无论是类,还是对象都可以被throws或者throw所操作。throws操作类,throw操作对象

   处理方式:

1,  声明抛出。告诉调用者功能会有问题。通过throws关键字对问题声明在功能上。

2,  进行捕捉。可以使用针对性的捕捉代码块完成

try

{

   //需要被检测的代码;

}

catch(异常类 变量)//该变量用于接收try检测到的异常对象

{

   //异常处理代码

}

finally

{

   //一定会被执行的代码

   //主要用于释放资源,无论是否发生异常,有些动作一定要执行,那么这些动、、//作定义在finally代码块中

}

throws throw关键字有什么区别?

throws用在函数上,用于功能声明异常,后面抛出的是异常类可以抛出多个,只要用于逗号隔开即可。

throw只能用于在函数内,用于抛出异常对象,额外特点,一旦执行,就可以结束功能。

自定义异常:

    对于常见的不正常情况,java都有对应的描述,比如角标越界,或者空指针等。

    对于自定义的程序中的出项的特有问题,java并没有给出对应的描述

    这时就需要我们按照面向对象的思想对这个问题进行描述,像异常一样将其封装成对象

   

    定义的方式:

1, 定义一个类,对问题进行描述。

2, 必须要让这个类继承异常类,具备可抛性

细节:

    1,定义功能,功能内部因为传入的参数问题,导致了功能会出现问题,这时为了解决这个问题,通常,我们都会将问题通过throws声明在函数上。

     目的:为了调用者在使用这个功能的时候,能明确处理方式,也就是说throws抛出的目的是为了让调用者预先定义好问题的处理方式。

    2,如果一个功能抛出多个异常。

           那么在调用该功能时,需要有多个catch进行每一个异常的指针处理,如果多个catch中有父类异常,一定要定义在最下面,否则编译失败。

3, 特殊部分:

       函数内throw抛出异常对象,函数上一定要用throws声明,否则编译失败,调用到声明异常的函数,要进行throws声明抛出,或者try catch捕捉,否则,编译失败。

     注意:异常分两种

1,  编译是被编译器检测的异常。

2,  编译时不被检测的异常。这种异常出现,编译时期是不在检查之列。这种异常称为运行时异常。也就是说函数内throw抛出运行时异常,不需要在函数上声明,即使声明了。调用者也不用一定给出预先处理方式,因为它不会导致编译失败

通常,不编写针对性的代码进行处理。一旦发生,就让程序停掉。为了对待吗进行修正。

                区分方式:

                    Exception中的一个特殊子类:RuntimeException就是运行时异常。

                    RuntimeException和其他子类都不需要编译时检测

                意味着:我们在自定义异常时,可以继承Exception,称为编译时被检测

的异常。也可以继承RuntimeException,称为运行时异常

     在进行异常捕捉时,代码快的不同组合情况

        1,try  catch  finally

        2,try  catch//没有需要一定被执行的代码-不需要资源的动作。
         3,try  finally。异常并没有被处理,但是却涉及到了资源的调用,资源需要被关                  

闭,所以就有了,将异常进行对外声明,因为没有catch,但是资源是在功能内部打开的,必须要功能内部关闭。就有了try和finally的组合。

     数据库中组合的模型

 try

{

   //1,连接数据库

   //2,存储数据,存储失败,会发生异常

}

catch(数据库异常 e)

{

   //异常处理代码

}

finally

{

   //3,关闭数据库连接,连接必须关闭,因为要释放资源

}

异常覆盖中的细节:

1,子类在覆盖父类时,如果父类中被覆盖的方法抛出了异常,

那么子类覆盖的方法只能抛出相同异常,或该异常的子类异常

2,如果父类的覆盖方法抛出了多个异常,子类在覆盖时,只能抛出这些异常的子集

3,如果被覆盖的方法没有抛出异常,子类也不允许抛出异常。如果子类中真的出现异常,只能在子类方法内进行try处理,绝对不允许throws声明,万一处理不了,可以抛出运行时异常


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 面向对象程序设计的基本特征: 面向对象程序设计的基本特征包括:封装、继承和多。封装是将数据和代码封装在一起,隐藏内部实现细节,提供对外的接口。继承是指从已有类派生出新的类,新类可以继承已有类的属性和方法,同时还可以添加新的属性和方法。多是指同一种操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。 2. 类与对象的区别: 类是对某一类事物的抽象描述,包含了该类事物的属性和方法;而对象则是类的一个实例化对象,具有该类事物的属性和方法。 3. 构造方法的特点: 构造方法是一种特殊的方法,用于创建对象时初始化对象的状。构造方法的名称必须与类名相同,没有返回值类型,并且在创建对象时自动调用。 4. 变量的种类及作用域: 变量包括局部变量、成员变量和类变量。局部变量是在方法或代码块中定义的变量,作用域仅限于该方法或代码块。成员变量是在类中定义的变量,作用域是整个类。类变量是用static关键字定义的变量,作用域是整个类,可以通过类名直接访问。 5. 传值和传引用: 传值是指将方法调用时实际参数的值传递给形式参数,形式参数和实际参数是两个不同的变量。传引用是指将方法调用时实际参数的引用传递给形式参数,形式参数和实际参数是同一个变量。 6. Static 及运行程序的过程: Static是Java中的一个关键字,可以用来修饰变量、方法和代码块。Static修饰的变量是类变量,Static修饰的方法是类方法,可以通过类名直接访问。当程序运行时,首先会加载类的字节码文件,然后创建类的实例,调用实例方法或类方法。 7. 包的作用: 包是Java中对类和接口的封装,可以将相关的类和接口组织在一起。包可以避免类名的冲突,方便类的管理和维护。 8. 静绑定和动绑定概念,并能根据静绑定和动绑定的基本原理来理解程序的运行结果: 静绑定是指在编译时确定方法的调用,根据变量的声明类型来确定方法的调用。动绑定是指在运行时确定方法的调用,根据变量的实际类型来确定方法的调用。当调用方法时,如果是静绑定,那么调用的是变量声明类型的方法;如果是动绑定,那么调用的是变量实际类型的方法。 9. 多的实现: 多是Java面向对象编程中的重要特性,可以提高代码的可扩展性和可维护性。多的实现可以通过继承、接口和重写实现。当父类引用变量指向子类对象时,可以调用子类重写的方法,实现多。 10. 通过类、抽象类、接口实现UML语言描述的类、抽象类、接口: UML是一种面向对象建模语言,可以用来描述类、接口、抽象类等。在Java中,可以通过类、抽象类、接口来实现UML语言描述的类、抽象类、接口。 11. 能区别异常处理中catch和finally语句: 在异常处理中,catch语句用于捕获异常并进行处理,finally语句用于在try语句块中的代码执行完毕后必定执行的代码块,无论是否发生异常。 12. 线程(重点):定义、多线程、临界资源,如何访问临界资源: 线程是程序的执行单元,Java中使用Thread类来实现线程。多线程是指程序中同时执行多个线程,可以提高程序的效率和响应速度。临界资源是指多个线程同时访问的共享资源,需要采用同步机制来保证数据的一致性和正确性,如使用synchronized关键字或Lock锁。 13. Java操作数据库:JDBC: JDBC是Java Database Connectivity的缩写,是Java中连接数据库的标准API。JDBC可以通过驱动程序连接数据库,执行SQL语句,获取查询结果等操作。JDBC可以连接各种类型的数据库,如MySQL、Oracle等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值