Java面对对象(二)

1、接口
与抽象类相似,接口同样不可以实例化,只能用于实现;
一般语法:
[访问权限] class 类名 implements 接口名 {
成员列表
}

接口中的成员修饰符是固定的。
•成员常量:public static final
•成员函数:public abstract

接口中的成员都是共有的。
一个类可以对接口进行多实现,也弥补了多继承带来的安全隐患,所以java对多继承进行了改良。用多实现方法来体现多继承的特性。
一个类可以继承一个类的同时,实现多个接口。
接口与接口之间是继承关系,而且可以多继承。
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。

接口的特点:
接口是对外暴露的规则。
接口是程序的功能扩展。
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有继承关系。

抽象类和接口异同:
相同:
1,都可以在内部定义抽象方法。
2,通常都在顶层。
3,都不可以实例化,都需要子类来实现。

不同点:
1,抽象类中可以定义抽象方法和非抽象方法,
而接口中只能定义抽象方法。
2,接口的出现可以多实现。
抽象类只能单继承。
也就是说:接口的出现避免了单继承的局限性。
3,继承和实现的关系不一致。继承:is a,实现:like a

接口的注意事项:
接口中不能定义非抽象方法,也就是说接口中不能包含有函数实体;
接口中的所有方法都默认为抽象方法,无需在每个方法前加abstract关键字;
接口中的所有变量都默认为常量;
接口的实现类应该提供对接口中所有抽象方法的具体实现,否则将成为抽象类;
与抽象类和它的继承类相似,也可以使用接口的引用指向其实现类的对象,从而达到动态多态的效果。

接口示例:

//定义接口
public interface IMyInterface
{
  /*接口中的所有方法都默认为抽象方法
    无需加abstract关键字*/
  public int add(int x, int y);
  public int sub(int x, int y);
}

//MyClass类实现于IMyInterface接口
public class MyClass
  implements IMyInterface {

  //实现接口中的抽象方法
  public int add(int x, int y) {
    return (x + y);
  }

  public int sub(int x, int y) {
    return (x - y);
  }
}

public class InterfaceDemo
{
  public static void main(String[] args)
  {
    //使用接口的引用指向实现类的实例
    IMyInterface obj = new MyClass();
    System.out.println("两数的和是:" + obj.add(20, 30));
    System.out.println("两数的差是:" + obj.sub(30, 20));
  }
}

2、多态
定义:某一类事物的多种存在形态。

例:动物中猫,狗。
人:男人,女人
动物:猫,狗。

猫这个对象对应的类型是猫类型
猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫称为 动物。
动物 y = new 猫();
• 动物是猫和狗具体事物中抽取出来的父类型。
• 父类型引用指向了子类对象。

1)多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。

2)多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。

3)多态的好处
多态的出现大大的提高程序的扩展性。

4)多态的弊端:
虽然提高了扩展性,但是只能使用父类的引用访问父类中的成员。

多态的特点:
成员函数:
• 编译时:要查看引用变量所属的类中是否有所调用的成员。
• 在运行时:要查看对象所属的类中是否有所调用的成员。
成员变量:
• 只看引用变量所属的类。

多态应用:

/* 
动物, 
猫,狗。 
*/  
abstract class Animal{  
         abstract void eat();  
 }  

class Cat extends Animal{  
   public void eat(){  
             System.out.println("吃鱼");  
   }  
   public void catchMouse(){  
             System.out.println("抓老鼠");  
   }  
}  

class Dog extends Animal{  
   public void eat(){  
             System.out.println("吃骨头");  
   }  
   public void kanJia(){  
             System.out.println("看家");  
  }  
}  

class DuoTaiDemo{  
   public static void main(String[] args){  

             Cat c1 = new Cat();  
             function(c1);  

             function(new Dog());  
             function(new Pig());                   
            function(new Cat());           
   }  
   public static void function(Animal a){  
           //Animal a = new Cat();父类的引用指向子类  类型提升。 向上转型。
             a.eat();  

           //instanceof : 用于判断对象的类型 对象intanceof 类型(类类型 接口类型)  
             if(a instanceof Cat){ 
                Cat c = (Cat)a; //强制将父类的引用,转成子类类型。向下转型。
                c.catchMouse();
             }else if(a instanceof Dog){
                Dog c = (Dog)a;
                c.kanJia();
            }  
   }  
}     

3 、内部类

定义:将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

内部类的访问规则:
1)内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2)外部类要访问内部类,必须建立内部类对象。

访问格式:
1)当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。
格式
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();

2)当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

    在外部其他类中,如何直接访问static内部类的非静态成员呢?
    new Outer.Inner().function();

    在外部其他类中,如何直接访问static内部类的静态成员呢?
    uter.Inner.function();

    注意:当内部类中定义了静态成员,该内部类必须是static的。
      当外部类中的静态方法访问内部类时,内部类也必须是static的。

当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。

3)内部类定义在局部时
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。

class Outer{
    private static  int x = 3;

    static class Inner{//静态内部类
        static void function(){
            System.out.println("innner :"+x);
        }
    }

    static class Inner2{
        void show(){
            System.out.println("inner2 show");
        }
    }

    public static void method(){
        //Inner.function();
        new Inner2().show();
    }
}

class  InnerClassDemo2{
    public static void main(String[] args) {
         Outer.method();
        //Outer.Inner.function();
        //new Outer.Inner().function();
        //直接访问内部类中的成员。
        //Outer.Inner in = new Outer().new Inner();
        //in.function();
    }
}

4、匿名内部类
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。

interface Demo  {  
    public abstract void run();  
}  

class Wai{  
    static int i = 9;  
    static class Nei{  
        static int y = 10;  
        public  static void run( int x){  
            i = x;  
            System.out.println(i);  
        }  
    }  
    public void fucntion(){  
        new Demo(){  
            public void run(){  
                System.out.println("haha");  
            }  
        }.run();  
        // 匿名内部类实现了Demo接口  
    }  

}  

class InnerTest{  
    public static void main(String[] args) {  
         Wai.Nei.run(11);  
        /*Wai w = new Wai(); 
        w.Nei().run(10);*/  
        new Wai().fucntion();  
    }  
} 

5、异常
异常:就是程序在运行时出现不正常情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。
对于异常分两种:
1,编译时被检测的异常。
2,编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

异常的体系
Throwable
• Error
通常出现重大问题如:运行的类不存在或者内存溢出等。
不编写针对代码对其处理
• Exception
在运行时运行出现的一起情况,可以通过try catch finally

Exception和Error的子类名都是以父类名作为后缀。

Throwable 中的方法:
getMessage()
• 获取异常信息,返回字符串。
toString()
• 获取异常类名和异常信息,返回字符串。
printStackTrace()
• 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
printStackTrace(PrintStream s)
• 通常用该方法将异常内容保存在日志文件中,以便查阅。

throws和throw:
throws用于标识函数暴露出的异常。
throw用于抛出异常对象。

throws与throw的区别:
• thorws用在函数上,后面跟异常类名。
• throw用在函数内,后面跟异常对象。

异常处理:
try{
需要检测的代码;
}
catch(异常类 变量){
异常处理代码;
}
finally{
一定会执行的代码;
}
Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)。

自定义异常:
1)自定义类继承Exception或者其子类。通过构造函数定义异常信息。
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。
只有这个体系中的类和对象才可以被throws和throw操作。
例:

 Class DemoException extends Exception{
    DemoException(String message){
    super(message);
    }
}

2)通过throw将自定义异常抛出。

异常细节:
RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。

6、包(package)
对类文件进行分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称的是 包名.类名。
包也是一种封装形式。

包之间的访问:
被访问的包中的类权限必须是public的。
类中的成员权限:public或者protected
protected是为其他包中的子类提供的一种权限

例如:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值