黑马程序员_JAVA之面向对象(封装,继承和多态)







------- android培训、java培训、期待与您交流!----------


面向对象


一.面向对象概述


定义:


面向对象(Object Oriented,OO)是软件开过过程中使用一种思维方式 


面向过程:强调功能行为,关注完成的过程


面向对象:将功能封装进对象,强调具备了功能的对象,不关注过程


面向对象与面向过程都是一种思想


面向对象是基于面向过程的
特点:


是一种更符合人们思考习惯的思想


可以将复杂的事情简单化


将程序由执行者转换成了指挥者




面向对象完成需求:


明确开发功能需求


查找具有该功能的类


如果不存在满足功能的类,则定义这样的类


创建该类对象,使用对象完成功能






面向对象三大特征:


封装(encapsulation)


继承(inheritance)


多态(polymorphism)


面向对象(类与对象概述)
1)我们如何描述现实世界事物
举例: 描述学生事物
姓名 , 年龄 , 性别 ....
学习 , 吃饭 , 睡觉 ....


属性:
就是该事物的描述信息
行为:
就是该事物能够做什么
我们学习编程语言,就是为了模拟现实中的事物,我们学习的Java语言最基本单位是类,所以,我们就应该把事物用一个类来体现。
由此我们就得到了现实中的事物和类的对应关系
事物

属性----------------- 成员变量
行为----------------- 成员方法
2)定义类其实就是定义类的成员(成员变量和成员方法)
a:成员变量和以前定义变量是一样的,只不过位置发生了改变.在类中,方法外
b:成员方法和以前定义方法是一样的,只不过把static去掉,后面在详细讲解static的作用
3)类和对象的概念
a:类:是一组相关的属性和行为的集合
b:对象:是该类事物的具体体现
c:举例:
类------学生
对象----班长就是一个对象


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">/* 
    学生事物: 
        属性: 年龄 , 姓名, 性别 ... 
        行为: 学习 , 吃饭, 睡觉 ... 
    学生类: 
        成员变量:   年龄 , 姓名, 性别 
        成员方法:   学习 , 吃饭, 睡觉 
     
    成员变量: 和之前定义变量一样,只不过位置不同,在类中,方法外 
    成员方法: 和之前定义方法一样,只不过去掉static 
*/  
class Student {  
  
    // 成员变量  
    String name = "张三";         // 姓名  
    int    age  = 24 ;              // 年龄  
    String sex  = "男" ;         //  性别  
  
    // 成员方法  
    // 学习  
    public void study(){  
        System.out.println("学生在学习....");  
    }  
  
    // 吃饭  
    public void eat(){  
        System.out.println("学习饿了该吃饭了.....");  
    }  
  
    // 睡觉  
    public void sleep(){  
        System.out.println("学习累了,该睡觉了....");  
    }  
  
}</span>  


类是如何使用的
A:创建对象


格式:


类名(一种抽象好的类型,实际上是自定义的数组类型) 对象名 = new 类名(); 创建对象必须加()


B:使用成员变量和成员方法


对象名.成员变量
对象名.成员方法名()  :调用方法必须加()




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">// 学生类  
class Student {  
  
    // 成员变量  
    // String name = "张三" ;         // 姓名  
    // int    age  = 24 ;               // 年龄  
    // String sex  = "男";               // 性别  
  
    String name ;       // null     // 姓名  
    int    age  ;       // 0        // 年龄  
    String sex ;        // null     // 性别  
  
    // 成员方法  
    // 学习  
    public void study(){  
        System.out.println("学生在学习...");  
    }  
  
    // 吃饭  
    public void eat(){  
        System.out.println("学习饿了该吃饭 ...");  
    }  
  
    // 睡觉  
    public void sleep(){  
        System.out.println("学习累了,该睡觉了....");  
    }  
}  
  
// 测试类  
class StudentDemo {  
      
    public static void main(String[] args){  
          
        // 创建对象格式:  类名 对象名 = new 类名();    
        Student s = new Student();  
          
        // 获取对象的成员变量  
        // 格式: 对象名.变量名  
        // String name = s.name ;  
        // int age = s.age ;  
        // String sex = s.sex ;  
  
        // 给成员变量赋值  
        s.name = "张三";  
        s.age = 24 ;  
        s.sex = "男";  
  
        // 输出  
        System.out.println(s.name + "---" + s.age + "---" + s.sex);  
  
        // 调用Student类中的方法  
        // 格式: 对象名.方法名(...)  
        s.study();  
        s.eat();  
        s.sleep();  
  
        System.out.println("----------------");  
  
        // 创建对象格式:  类名 对象名 = new 类名();    
        Student s2 = new Student();  
  
        // 输出  
        System.out.println(s2.name + "---" + s2.age + "---" + s2.sex);  
  
        // 调用Student类中的方法  
        // 格式: 对象名.方法名(...)  
        s2.study();  
        s2.eat();  
        s2.sleep();  
    }  
}</span>  
成员变量和局部变量的区别
(1)定义位置区别:
成员变量:定义在类中,方法外
局部变量:定义在方法中,或者方法声明上
(2)初始化值的区别:
成员变量:都有默认初始化值
局部变量:没有默认初始化值,要想使用,必须先赋值。
(3)存储位置区别:
成员变量:存储在堆中
局部变量:存储在栈中
(4)生命周期区别:
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法调用完毕而消失,更严谨地说当局部变量的作用域结束时,即被销毁


就近原则:局部变量有,就用局部变量,局部变量没有,就找成员变量,如果成员变量也没有就报错


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">  
class Demo {  
  
    int b ;  
  
    int a = 40 ;  
      
    public void show(){  
  
        // 错误的: 可能尚未初始化变量a  
        // int a ;  
        // System.out.println(a);  
  
        int a = 30 ;  
        System.out.println(a);  
    }  
  
}  
  
  
class VariableDemo {  
  
    public static void main(String[] args){  
          
        // 创建Demo对象  
        Demo d = new Demo();  
  
        // 调用show方法  
        d.show();  
  
        // 获取b  
        System.out.println(d.b);  
          
    }  
  
}</span>  


二.继承
概述:


多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,


那么多个类无需再定义这些属性和行为,只要继承那个类即可






这多个类称为子类,单独这个类称为父类或者超类


子类可以直接访问父类中非私有的成员变量与成员方法






子类在继承父类后,仍可以定义只属于子类自己的方法,>>子类比父类更强大


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;">class Demo5  
{  
    public static void main(String[] args)  
    {  
        Cat cat = new Cat();  
        cat.eat();  
        Dog dog = new Dog();  
        dog.eat();  
  
        System.out.println(cat.name);  
        //System.out.println(cat.age);  
    }  
}  
class Animal  
{  
    String name = "四不像";  
    private int age = 20;  
  
    public void eat(){  
        System.out.println("吃了");  
    }  
    public void sleep(){  
        System.out.println("睡了");  
    }  
}  
  
class Cat extends Animal  
{  
    public void catchMouse(){  
        System.out.println("猫抓老鼠的方法");  
    }  
}  
class Dog extends Animal  
{  
}  
class Person extends Animal  
{  
}  
</span>  
继承的特点:
java只支持单继承不支持多继承


java支持多层继承


任何类都直接或者间接继承自Object类




注意事项:


不要为了某个功能而去继承,需要满足”is a”的关系


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo6   
{  
    public static void main(String[] args)   
    {  
        Manager m = new Manager();  
        m.eat();  
        System.out.println(m.hashCode());  
  
        Boss boss = new Boss();  
        boss.eat();  
        boss.keepMoney();  
    }  
}  
class Animal  
{  
    String name = "四不像";  
    private int age = 20;  
  
    public void eat(){  
        System.out.println("吃了");  
    }  
    public void sleep(){  
        System.out.println("睡了");  
    }  
}  
  
class Cat extends Animal  
{  
    public void catchMouse(){  
        System.out.println("猫抓老鼠的方法");  
    }  
}  
class Dog extends Animal  
{  
    public void keepMoney() {  
        System.out.println("钱看住了!");  
    }  
}  
class Person extends Animal  
{  
}  
  
class Manager extends Person  
{  
}  
  
//不同种类的继承是不应该存在,不能为了某个功能而继承不同种类的类。  
//继承时必须符合"is a"的关系。  
//如果仅仅是需要里边的某个功能的话,我们在后边学习的"实现"可以完成  
class Boss extends Dog  
{  
}</span>  


继承后成员特点:
成员方法:
子类可以直接访问父类的非私有成员方法


当子父类方法一样时,方法重写.


当出现方法重写时,没有明确地指定要调用super的方法时,一直调用的子类重写后的方法


代码演示




[java] view plaincopy
<span style="font-family:SimHei;">class Demo8   
{  
    public static void main(String[] args)   
    {  
        Cat cat = new Cat();  
        cat.eat();  
        //cat.sleep();  
        //cat.catchMouse();  
    }  
}  
class Animal  
{  
    public void eat(){  
        System.out.println("吃了");  
    }  
    public void sleep(){  
        System.out.println("睡了");  
    }  
}  
  
class Cat extends Animal  
{  
    public void catchMouse(){  
        System.out.println("猫抓老鼠");  
        //super.eat();  
        super.eat();  
        eat();  
        this.eat();  
    }  
      
    public void eat(){  
        System.out.print("喵,");  
        super.eat();  
    }  
}</span>  


方法重载与方法重写


重载:一般是在同一个类中,(但是也有可能在子父类中包含重载关系)


规则:


方法名相同


参数列表不同:类型不同,个数不同,顺序不同


与其他内容都无关


重写:一定涉及两个或两个以上的类,并且有子父类关系


规则:


访问权限:相同 或者 子类访问权限大于父类访问权限


函数名:相同


参数列表:相同


返回值类型:


void符合基本类型的规律


基本数据类型:必须相同


引用数据类型:相同或者不同时,父类返回值是子类返回值的父类是可以的.(子类返回值小于父类)
静态方法只能覆盖静态方法


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;"><span style="font-size:14px;">class Demo9  
{  
    public static void main(String[] args)   
    {  
        Cat cat = new Cat();  
        cat.eat();  
        //cat.eat("fish");  
        cat.sleep();  
    }  
}  
//访问权限    默认的<public  
class Animal  
{  
    public Fu eat(){  
        System.out.println("吃了");  
        return new Fu();  
    }  
  
    public static void sleep(){  
        System.out.println("父类的静态方法");  
    }  
      
    /* 
    public void eat(String food){ 
        System.out.println("吃了"+food); 
    } 
    */  
}  
  
class Cat extends Animal  
{  
    public Zi eat(){  
        System.out.println("喵,吃了");  
        return new Zi();  
    }  
      
    public static void sleep(){  
        System.out.println("子类重写的静态方法");  
    }  
      
}  
  
class Fu{}  
class Zi extends Fu{}</span><span style="font-size:18px;">  
</span></span>  


继承后的成员特点:
构造方法:
构造方法不能继承
子类的构造方法会默认调用父类的空参构造(在子类的每一个构造方法的第一行都有默认的super())


如果使用父类的成员变量,则在子类的构造方法中可以通过子类构造方法调用父类构造方法的方式给父类成员变量赋值


在访问时,均使用的是父类的成员变量


父类构造方法负责对成员变量初始化供子类对象使用,而不是创建父类对象


父类没有空参构造,子类构造方法可以手动调用父类的其他参数的构造,或者为父类补充上空参构造


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo10  
{  
    public static void main(String[] args)   
    {  
        Cat cat = new Cat("Tom");  
        //Animal a = new Animal();  
        System.out.println(cat.getName());  
  
        //Cat cat2 = new Cat();  
        //System.out.println(cat2.getName());  
    }  
}  
  
class Animal  
{  
    private String name = "哺乳动物";  
      
    public Animal(){  
        System.out.println("我是父类Animal中的空参构造");  
    }  
      
    public Animal(String name){  
        this.name = name;  
        System.out.println("我是父类Animal中的有一个参数的构造");  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getName() {  
        return name;  
    }  
}  
  
class Cat extends Animal  
{  
    public Cat(){  
        //super();  
        super("庞中华");  
        System.out.println("我是子类Cat中的空参构造");  
    }     
  
    public Cat(String name){  
        //super();  
        super(name);  
        System.out.println("我是父类Animal中的有一个参数的构造");  
    }  
  
}</span>  




this关键字与super关键字


super:


方式一:用来访问父类存储空间的成员


方式二:用来在子类的构造方法中调用父类的构造方法


this:


方式一:用来访问子类自己的成员


方式二:用来在本类的构造方法中调用本类的其他构造方法






this与super调用构造方法都必须放在第一行
子父类构造方法设计原则:至少有一个构造必须先访问父类构造,再父类构造完毕之后,再访问本类构造


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo11   
{  
    public static void main(String[] args)   
    {  
        Cat cat = new Cat("kitty");  
        //cat.eat();  
        cat.catchMouse();  
    }  
}  
class Animal  
{  
    String name = "哺乳动物";  
      
    public Animal(){  
        System.out.println("我是父类Animal中的空参构造");  
    }  
      
    public Animal(String name){  
        this.name = name;  
        System.out.println("我是父类Animal中的有一个参数的构造");  
    }  
  
    public void eat(){  
        System.out.println("我是父类中的eat方法");  
    }  
  
}  
  
class Cat extends Animal  
{  
    //String name = "Tom";  
    int age = 10;  
  
    public Cat(){  
        //super();  
        System.out.println("我是子类Cat中的空参构造");  
    }     
  
    public Cat(String name){  
        super(name);  
        System.out.println("我是父类Animal中的有一个参数的构造");  
    }  
  
    public Cat(int age) {  
        this.age = age;  
    }  
  
    public Cat(String name,int age) {  
        //super(name);  
        //仅仅给年龄赋值,不管姓名时  
        this(age);  
    }  
  
    public void eat(){  
        System.out.println("我是子类中的eat方法");  
    }  
  
    public void catchMouse(){  
  
        System.out.println("我是子类中的catchMouse方法"+super.name);  
        super.eat();  
    }  
}</span>  


final关键字:
最终修饰符


修饰类:类无法被继承


修饰方法:方法无法被重写


修饰变量


成员变量:


必须被赋值,只能赋值一次


赋值动作需要在对象创建完成之前执行


局部变量:


只能赋值一次


代码演示:


[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo   
{  
    public static void main(String[] args)   
    {  
        Cat cat = new Cat("kitty");  
        //Cat cat = new Cat();  
        //cat.name = "Tom";  
        System.out.println(cat.name);  
        cat.myMethod();  
        cat.myMethod2("石家庄");  
        cat.myMethod3(28);  
        Person p = new Person("段正淳",30);  //0x1234  
        cat.myMethod4(p);  
    }  
}  
  
//final class Animal 被final修饰的类无法被继承  
class Animal  
{  
    public final void method(){}  
}  
  
class Cat extends Animal  
{  
    /*子类无法重写父类中final修饰的方法 
    public void method(){ 
        System.out.println("我是子类的方法"); 
    } 
    */  
    //final String name = "Tom";  
    final String name;  
    //public Cat(){}  //如果同时还存在空参不给name赋值的构造,则会报错:可能尚未初始化  
      
    public Cat(String name){  
        this.name = name;  
    }  
      
    //定义方法,测试final修饰局部变量  
    public void myMethod(){  
        final String city = "北京";  
        //city = "张家口";  final修饰的变量只能赋值一次  
        System.out.println(city);  
    }  
  
    public void myMethod2(final String city){  
        //city = "北京";  
        //city = "张家口";  final修饰的变量只能赋值一次  
        System.out.println(city);  
    }  
  
    public void myMethod3(final int age){  
        //age = 30;  
        System.out.println(age);  
    }  
  
    public void myMethod4(final Person p){//0x1234  
        p.name = "段延庆";  
        p.age = 40;  
        //p = new Person("段誉",18); //0x2234  
    }  
}</span>  




三.多态:
概述:同一种事物的多种形态
java中父类引用指向子类对象


前提:


必须多态的两个类间存在关系(继承/实现)


要有方法覆盖操作,否则没有意义


java中父类引用指向子类对象


代码演示:




[java] view plaincopy
<strong><span style="font-family:SimHei;">class Demo2   
{  
    public static void main(String[] args)   
    {  
        Animal a = new Animal();    //动物是动物  
        Cat c = new Cat();          //猫是猫  
  
        Animal a2 = new Cat();      //猫是动物  
        //Cat c2 = new Animal();      //动物是猫  
    }  
}  
  
class Animal  
{  
}  
  
class Cat extends Animal  
{  
}</span></strong>  
多态的优点及特点:
优点:开发当中要符合开闭原则:对修改关闭,对扩展开放
多态的存在提高了程序的扩展性和后期可维护性


特点(规则):


成员变量:


编译期:看左边  / 看父类


运行期:看左边  / 看父类


成员函数:


编译期:看左边  / 看父类


运行时:看右边  / 看子类






只有在调用方法时,检查子类是否有重写,子类重写调用子类重写的方法,其余所有内容均看父类类型
只有调用方法看子类


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;">class Demo3  
{  
    public static void main(String[] args)   
    {  
        //使用多态的方式创建一个Cat对象  
        Animal a = new Cat();     
          
        //System.out.println(a.name);  
        a.methodFu();  
        //a.methodZi();  
    }  
}  
  
class Animal  
{  
    //String name = "花花";  
    public void methodFu(){  
        System.out.println("我是父类中的方法");  
    }  
}  
  
class Cat extends Animal  
{  
    String name = "曹操";  
  
    /*多态时,调用父类没有的子类方法不可以 
    public void methodZi(){ 
        System.out.println("我是子类中的方法"); 
    } 
    */  
  
    //子类重写父类的方法  
    public void methodFu(){  
        System.out.println("我是子类中重写的父类方法");  
    }  
}</span>  


向上向下转型
向上转型:引用变量为父类时,子类实例对象可以自动提升为父类类型  
向下转型:可以使用强制类型转换,完成向下转型 
代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo4  
{  
    public static void main(String[] args)   
    {  
        //第一次调用  
        Animal a = new Cat();  
        method(a);  
        //第二次调用  
        Cat cat = new Cat();  
        method(cat);  
        //第三次调用  
        Cat cat2 = new Cat();  
        method2(cat2);  
  
  
        //使用第四调用的方法演示向下类型转换  
        Cat cat3 = new Cat();  
        method3(cat3);  
        Animal a2 = new Animal();  
        method3(a2);  
    }  
    //第一次调用 Animal a >>  Animal b  >>  Animal c  
    //第二次调用 Cat cat  >>  Animal b  >>  Animal c  
    public static void method(Animal b){    
        Animal c = b;  
        c.methodFu();  
    }  
    //第三次调用 Cat cat  >>  Animal b  
    public static void method2(Animal b){    
          
        b.methodFu();  
    }  
    //第四次调用 Cat cat  >>  Animal b  >>  Animal c  >> Cat d(此步骤为强转)   这样是可以的   对象原本就是Cat可以强转成Cat  
    //Animal a2  >>  Animal b  >>  Animal c  >> Cat d(此步骤为强转)   这样是不可以的          对象原本不是Cat不能强转成Cat  
    public static void method3(Animal b){    
        Animal c = b;  
        //c.methodZi();  父类类型没有methodZi方法  
        Cat d = (Cat)c;  
        d.methodFu();  
        d.methodZi();  //强转成子类对象后,可以调用子类对象自己的方法  
    }  
}  
class Animal  
{  
    String name = "kitty";  
    public void methodFu(){  
        System.out.println("我是父类中的方法");  
    }  
}  
class Cat extends Animal  
{  
      
    public void methodFu(){  
        System.out.println("我是子类中重写父类的方法");  
    }  
  
    public void methodZi(){  
        System.out.println("我是子类中的特有方法");  
    }  
}  
  
class Dog extends Animal  
{  
      
    public void methodFu(){  
        System.out.println("我是子类中重写父类的方法");  
    }  
  
    public void methodZi(){  
        System.out.println("我是子类中的特有方法");  
    }  
}</span>  


四.抽象类:
包含抽象方法的类就是抽象类(判断的方法之一)


抽象类不一定包含抽象方法


抽象类可以有非抽象方法


抽象类中可以没有方法


抽象方法:


将多个对象的共性功能抽取出来,只有方法声明.没有方法体!


抽象声明格式:


声明一个方法是抽象的:在方法前加abstract关键字


声明一个类是抽象的:在类前加abstract关键字


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;">class Demo9   
{  
    public static void main(String[] args)   
    {  
        System.out.println("Hello World!");  
    }  
}  
  
abstract class Animal  
{  
    //public abstract void eat();  
    /*public void sleep(){ 
        System.out.println("睡"); 
    } 
    */  
}</span>  


抽象类的特点
抽象类无法实例化


抽象类通过多态的形式创建其子类实例对象


子类需要将抽象父类的抽象方法均覆盖才可以实例化,否则依然是抽象类


抽象类强制子类必须实现抽象方法


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo10  
{  
    public static void main(String[] args)   
    {  
        Animal animal = new Cat();  
        //Animal animal = new BoSiCat();  
    }  
}  
abstract class Animal  
{  
    public abstract void eat();  
    public abstract void sleep();  
}  
  
abstract class Cat extends Animal  
{  
    /* 
    public void eat() { 
        System.out.println("吃鱼!"); 
    } 
    */  
      
    //public abstract void eat();  
    public void sleep(){  
        System.out.println("睡了");  
    }  
      
}  
  
class BoSiCat extends Cat  
{  
    public void eat() {  
        System.out.println("吃鱼!");  
    }  
}</span>  






接口:
比抽象类更抽象的表现形式






抽象类可以有非抽象方法


接口中全部必须是抽象方法






格式:


定义接口:interface XX {}


使用接口:class YY implements XX{}  类实现接口


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;">class Demo11   
{  
    public static void main(String[] args)   
    {  
        MyInterface mi = new MyClass();  
        mi.method();  
    }  
}  
  
interface MyInterface  
{  
    public abstract void method();  
}  
  
class MyClass implements MyInterface  
{  
    public void method() {  
        System.out.println("我是类中重写的接口方法");  
    }  
}</span>  
java支持类同时实现多个接口
java支持类在继承一个类的同时,实现多个接口
java支持接口多继承接口




接口的成员特点:成员变量与成员函数均为固定的修饰符!




构造方法:没有!
public static final XXX  xxx = yyy;  >>定义一个常量
成员变量:public static final
成员方法:public abstract 




代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo13  
{  
    public static void main(String[] args)   
    {  
        MyInterface mf = new MyClass();  
        System.out.println(MyInterface.age);  
    }  
}  
interface MyInterface  
{  
    String name = "杨幂";  
    int age = 28;  
  
    public abstract void method();  
}  
class MyClass implements MyInterface  
{  
    public void method(){  
        System.out.println("abc");  
    }  
}</span>  




五.内部类:
在同一个文件中定义多个类时,只有一个被public修饰的类与文件名相同,其他类不能使用public修饰
内部类:


定义类中的类


内部类可以访问外部类的成员


而外部类要访问内部类中的成员必须要建立内部类的对象


内部类分类:


成员内部类


局部内部类


创建成员内部类对象的格式!!!:
Outer.Inner x = new Outer().new Inner();




记忆方式:对比成员变量与成员函数


访问成员变量:对象.属性


调用成员方法:对象.方法名()


创建成员内部类对象: 对象.new 内部类(参数)








代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">public class Demo11  
{  
    public static void main(String[] args)   
    {  
        //定义一个内部类引用变量  
        //Outer.Inner x    
        //创建一个外部类对象  
        //Outer out = new Outer();  
        //通过一个外部类对象创建其内部类对象  
        //out.new Inner();  
  
        Outer.FieldInner x = new Outer().new FieldInner();  
        x.inMethod();  
  
        Outer out = new Outer();  
  
        //访问成员变量  
        String name = out.name;  
        System.out.println(name);  
  
        //调用成员方法  
        out.method();  
  
        //创建成员内部类对象  
        Outer.FieldInner inner = out.new FieldInner();  
        //Outer.FieldInner inner = new out.FieldInner();  错误的格式,会将out.误认为包名  
        inner.inMethod();  
    }  
}  
  
class Outer  
{  
    String name = "梁洛施";  
    //成员内部类  
    class FieldInner  
    {  
        //String name = "梁家辉";  
        public void inMethod(){  
            //String name = "梁朝伟";  
            System.out.println(name);  
        }  
    }  
      
    public void method(){  
        System.out.println("我是外部类的一个普通方法");  
    }  
}</span><span style="font-size:18px;">  
</span>  
成员内部类位于成员位置,可以使用修饰符修饰,符合修饰符的规则
private:外部类外部无法创建内部类对象,只能再外部类的方法中创建内部类对象
代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo12  
{  
    public static void main(String[] args)   
    {  
        Outer out = new Outer();  
        //System.out.println(out.name);  
        out.method();  
  
        //在Outer以外无法直接创建一个私有化的内部类FieldInner对象  
        //Outer.FieldInner x = new Outer().new FieldInner();  
  
          
    }  
}  
  
class Outer  
{  
    public String name = "梁洛施";  
    //成员内部类  
    private class FieldInner  
    {  
        public void inMethod(){  
            System.out.println(name);  
        }  
    }  
      
    public void method(){  
        //成员内部类私有化之后,外部无法创建对象,可以通过Outer的方法直接创建  
        //外部类知道有内部类对象,直接创建内部类对象即可  
        FieldInner fi = new FieldInner();  
        fi.inMethod();  
  
        //了解  
        Outer.FieldInner x = new Outer().new FieldInner();  //该种方式可以,但是多创建了一个没有必要的外部类对象  
        x.inMethod();  
    }  
}</span>  
局部内部类
无法使用Outer.Inner进行访问 
访问格式:在所在方法内创建对象进行方法调用
同时可以访问所在局部中的局部变量,但必须是被final修饰的
必须先定义再使用
代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo14  
{  
    public static void main(String[] args)   
    {  
        Outer out = new Outer();  
        out.outMethod();  
    }  
}  
  
class Outer  
{  
    String name = "梁洛施";  
  
    public void outMethod(){  
        final String name = "梁咏琪";  
  
        //局部内部类  
        class MethodInner  
        {  
            public void method(){  
                System.out.println("我是局部内部类的方法");  
                System.out.println(name);  
            }  
        }  
  
        MethodInner mi = new MethodInner();  
        mi.method();  
    }  
  
}</span>  


匿名内部类
在通过简写形式定义一个没有类名的类


在创建一个对象


匿名内部类的使用格式!!!:


new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)};


类名或者接口名:要被继承的类或者要被实现的接口


即 匿名内部类是创建了一个抽象类或者接口的子类实例对象


代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo16   
{  
    public static void main(String[] args)   
    {  
        //以前有名字的类:第一步定义有名字的类    第二步创建对象,使用对象  
  
        //有名字的对象 有名字的类  
        Fu 对象名 = new 类名();  
        对象名.method();  
  
        //没名字的匿名对象 有名字的类  
        new 类名().method();  
  
        System.out.println("===============================================");  
  
        //有名字的对象  没有名字的类  
        Fu noNameObject = new Fu() {  
            public void method() {  
                System.out.println("我是匿名内部类1重写的父类方法");  
            }  
        };  
  
        noNameObject.method();  
  
        //没有名字的对象  没有名字的类  
        new Fu() {  
            public void method() {  
                System.out.println("我是匿名内部类2重写的父类方法");  
            }  
        }.method();  
    }  
}  
  
abstract class Fu  
{  
    public abstract void method();  
}  
  
class 类名 extends Fu  
{  
    public void method() {  
        System.out.println("我是子类重写的父类方法");  
    }  
}</span>  




通常在使用接口类型参数的方法上,并该接口中的方法不超过三个时,可以将匿名内部类作为参数传递
new 类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容.)};




代码演示:




[java] view plaincopy
<span style="font-family:SimHei;font-size:14px;">class Demo17  
{  
    public static void main(String[] args)   
    {  
        MyInterface mi = new MyInterface() {  
                public void method() {  
                    System.out.println("大毛");  
                }  
                public void method2() {  
                    System.out.println("二毛");  
                }  
                public void method3() {  
                    System.out.println("三毛");  
                }  
                public void method4() {  
                    System.out.println("小明");  
                }  
        };  
  
        aa(mi);  
        System.out.println("=============================");  
  
        aa(new MyInterface() {  
                public void method() {  
                    System.out.println("大毛");  
                }  
                public void method2() {  
                    System.out.println("二毛");  
                }  
                public void method3() {  
                    System.out.println("三毛");  
                }  
                public void method4() {  
                    System.out.println("小明");  
                }  
        });  
  
        System.out.println("=============================");  
        MyClass mc = new MyClass();  
        aa(mc);  
  
        System.out.println("=============================");  
        MyInterface mf = new MyClass();  
        aa(mf);  
  
    }  
  
    public static void aa(MyInterface mi) {  
        mi.method();  
        mi.method2();  
        mi.method3();  
        mi.method4();  
    }  
}  
  
//定义一个接口里边有四个方法  
interface MyInterface  
{  
    public abstract void method();  
    abstract void method2();  
    public void method3();  
    void method4();  
}  
  
class MyClass implements MyInterface  
{  
        public void method() {  
            System.out.println("大毛");  
        }  
        public void method2() {  
            System.out.println("二毛");  
        }  
        public void method3() {  
            System.out.println("三毛");  
        }  
        public void method4() {  
            System.out.println("小明");  
        }  
}</span>  








                    







































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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值