黑马程序员--Java面向对象_黑马java面向对象-程序员宅基地

技术标签: java  黑马程序员  

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

概述

面向对象是基于面向过程的编程思想。

面向过程:强调的是每一个功能的步骤
面向对象:强调的是对象,然后由对象去调用功能

特点
A:是一种更符合我们思想习惯的思想
B:可以将复杂的事情简单化
C:将我们从执行者变成了指挥者

特征

封装性

封装有两个含义。
一是把对象的属性和行为堪称一个密不可分的整体,将两者封装在一个不可分割的独立单位中(对象)。

二是指“信息隐藏”,把不需要让外界知道的信息隐藏起来,有些对象的属性和行为外界可以知道和使用,但不允许修改,另一些属性或行为,不允许外界知道,只允许使用对象的功能。

继承性

继承是提高软件开发效率的重要手段。

继承是首先拥有反映事物一般特性的类,然后在这个基础上派生出反映特殊事物的类。

例如已有普通汽车的类,该类中描述了汽车的普通属性和行为,如四个轮子,发动机,方向盘等等,
可以在这个基础上生产跑车的类,跑车是继承于汽车,跑车不但有用汽车的全部属性和行为,还增加跑车自己特有的属性和行为。

面向对象程序设计中的继承机制大大增加了程序代码的可复用性,提高软件开发效率,降低程序产生错误的可能性,也为程序的修改扩充提供便利。

多态性

多态是面向对象程序设计的有一个重要特征,多态允许程序中出现重名现象。java语言中含有方法重载和对象多态两种形式的多态。

方法重载:在一个类中,允许多个方法使用同一个名字,但方法的参数不同,完成的功能也不同。

对象多态:子类对象可以与父类对象进行相互转换,而且根据其使用的子类不同,完成的功能也不同。

多态的特性使程序的抽象程度和简捷程度更高,有助于程序设计人员对程序的富足协同开发。

面向对象就是一种常见的思想,符合人们的思考习惯。
面向对象的出现,让复杂的问题简单化。
面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者。

类与对象

类与对象是Java中最基本,但也是最重要的组成部分。

其实类与现实中的事物有着相似的地方
成员变量 – 事物属性
成员方法 – 事物行为

类:是一组相关的属性和行为的集合。是一个抽象的概念。
对象:是该类事物的具体存在,是一个具体的实例。

例如:学生是一个群体而不是指具体的某个人。我们就可以把学生看成一个类。
三年二班的周杰伦是一个具体的人,那么他就是一个具体的对象,不过他显然也属于学生这个群体。
每个学生都有名字和年龄,这两个属性我们就可以看成是一个类的成员变量。但是每个学生的名字和年龄都是一样的吗?显然不是,这时候对象就派上用场了,我们想得到周杰伦这个对象,那就直接new一个对象,然后分别给名字和年龄这两个属性赋上具体的数据,最后我们就得到了周杰伦的具体对象。
每个学生都要吃饭睡觉上厕所,这三个动作就是类的成员方法,所有的学生都要吃饭睡觉上厕所,周杰伦呢?当然也得要。。所以我们就知道了原来类里面有什么方法,那么它的对象就必须要有什么方法。

class Student {
    //定义变量
    //姓名
    String name;
    //年龄
    int age;
    //地址
    String address;

    //定义方法
    //学习的方法
    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();

        System.out.println(s.name+"---"+s.age+"---"+s.address);


        //给成员变量赋值
        s.name = "李延旭";
        s.age = 21;
        s.address = "北京";
        //赋值后的输出
        System.out.println(s.name+"---"+s.age+"---"+s.address);

        //调用方法
        s.study();
        s.eat();
        s.sleep();
    }
}

成员变量和局部变量的区别:
1.在类中的位置不同
成员变量定义在类中,整个类中都可以访问。
局部变量定义在函数,语句,局部代码块中,只在所属的区域有效。

2.再内存中的位置不同
成员变量存在于堆内存的对象中
局部变量存在于栈内存的方法中

3.生命周期不同
成员变量随着对象的创建而存在,随着对象的消失而消失。
局部变量随着所属区域的执行而存在,随着所属区域的结束而释放。

4.初始化值不同
成员变量都有默认初始化值
局部变量没有默认初始化值

成员方法:定义格式和以前一样,就是去掉了static。

类作为形式参数
如果你看到一个方法需要的参数是一个类名,就应该知道这里实际需要的是一个具体的对象

/*
    形式参数的问题:
        基本类型:形式参数的改变不影响实际参数
        引用类型:形式参数的改变直接影响实际参数
*/
//形式参数是基本类型
class Demo {
    public int sum(int a,int b) {
        return a + b;
    }
}

//形式参数是引用类型
class Student {
    public void show() {
        System.out.println("我爱学习");
    }
}

class StudentDemo {
    //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
    public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
        s.show();
    }
}

class ArgsTest {
    public static void main(String[] args) {
        //形式参数是基本类型的调用
        Demo d = new Demo();
        int result = d.sum(10,20);
        System.out.println("result:"+result);
        System.out.println("--------------");

        //形式参数是引用类型的调用
        //需求:我要调用StudentDemo类中的method()方法
        StudentDemo sd = new StudentDemo();
        //创建学生对象
        Student s = new Student();
        sd.method(s); //把s的地址给到了这里
    }
}

匿名对象

就是没有名字的对象。

匿名对象的应用场景:
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
那么,这种匿名调用有什么好处吗?
有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。

B:匿名对象可以作为实际参数传递

class Student {
    public void show() {
        System.out.println("我爱学习");
    }
}

class StudentDemo {
    public void method(Student s) {
        s.show();
    }
}

class NoNameDemo {
    public static void main(String[] args) {
        //带名字的调用
        Student s = new Student();
        s.show();
        s.show();
        System.out.println("--------------");

        //匿名对象
        //new Student();
        //匿名对象调用方法
        new Student().show();
        new Student().show(); //这里其实是重新创建了一个新的对象
        System.out.println("--------------");


        //匿名对象作为实际参数传递
        StudentDemo sd = new StudentDemo();
        //Student ss = new Student();
        //sd.method(ss); //这里的s是一个实际参数
        //匿名对象
        sd.method(new Student());

        //在来一个
        new StudentDemo().method(new Student());
    }
}

封装

隐藏实现细节,提供公共的访问方式

好处:
A:隐藏实现细节,提供公共的访问方式
B:提高代码的复用性
C:提高代码的安全性

private

是一个权限修饰符,私有的意义,可以修饰成员变量和成员方法
被其修饰的成员只能在本类中被访问

private的应用:
把所有的成员变量给private了
提供对应的getXxx()/setXxx()方法

class Demo {
    //int num = 10;
    //用private修饰
    private int num = 10;

    public void show() {
        System.out.println(num);
    }

    private void method() {
        System.out.println("method");
    }

    public void function() {
        method();
    }
}

class PrivateDemo {
    public static void main(String[] args) {
        Demo d = new Demo();
        //不能使用方法私有的成员变量
        //System.out.println(d.num);
        d.show();
        //不能访问私有的成员方法
        //d.method();
        d.function();
    }
}
//定义学生类
class Student {
    //姓名
    private String name;
    //年龄
    private int age;

    //姓名获取值
    public String getName() 
    {
        return name;
    }
    //姓名设置值
    public void setName(String n)
    {
        name = n;
    }
    //年龄获取值
    public int getAge()
    {
        return age;
    }
    //年龄赋值
    public void setAge(int a) 
    {
        age = a;
    }
}

//测试类
class StudentTest 
{
    public static void main(String[] args) 
    {
        //创建学生对象
        Student s = new Student();

        //使用成员变量
        System.out.println(s.getName()+"---"+s.getAge());

        //给成员变量赋值
        //通过方法给赋值
        s.setName("李延旭");
        s.setAge(21);
        System.out.println(s.getName()+"---"+s.getAge());
    }
}

this

当前类的对象引用。简单的记,它就代表当前类的一个对象。
注意:谁调用这个方法,在该方法内部的this就代表谁。

this的应用场景:
解决局部变量隐藏成员变量

class Student {
    //姓名
    private String name;
    //年龄
    private int age;

    //姓名获取值
    public String getName() {
        return name;
    }

    //姓名设置值
    public void setName(String name) { 
        this.name = name;
    }

    //年龄获取值
    public int getAge() {
        return age;
    }

    //年龄赋值
    public void setAge(int age) {
        this.age = age;
    }
}
  • 构造方法

给对象的数据进行初始化

格式:
A:方法名与类名相同
B:没有返回值类型,连void都没有
C:没有具体的返回值

class Student {
    private String name; //null
    private int age; //0

    public Student() {
        System.out.println("这是构造方法");
    }
}

class ConstructDemo {
    public static void main(String[] args) {
        //创建对象
        Student s = new Student();
        System.out.println(s); 
    }
}

构造方法的注意事项:
A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法

给成员变量赋值有两种方式:
A:setXxx()
B:构造方法

static

针对多个对象有共同的这样的成员变量值的时候,Java就提高了一个关键字来修饰:static。
static的特点:(它可以修饰成员变量,还可以修饰成员方法)
A:随着类的加载而加载,回想main方法。
B:优先于对象存在
C:被类的所有对象共享

什么时候使用静态?
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
举例:
饮水机(用静态修饰)
水杯(不能用静态修饰)
D:可以通过类名调用
其实它本身也可以通过对象名调用。推荐使用类名调用。

static关键字注意事项
A:在静态方法中是没有this关键字的
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
B:静态方法只能访问静态的成员变量和静态的成员方法

静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法

非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。

简单记:静态只能访问静态。

main方法的格式讲解

public static void main(String[] args) {…}

public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。

static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。

void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。

main:是一个常见的方法入口。我见过的语言都是以main作为入口。

String[] args:这是一个字符串数组。值去哪里了?
这个东西到底有什么用啊?怎么给值啊?
这个东西早期是为了接收键盘录入的数据的。
格式是:
java MainDemo hello world java

代码块

在Java中,使用{}括起来的代码被称为代码块

根据其位置和声明的不同,可以分为
局部代码块:局部位置,用于限定变量的生命周期。

构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。

静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
作用:一般是对类进行初始化。

静态代码块,构造代码块,构造方法的执行顺序?
静态代码块 – 构造代码块 – 构造方法

静态代码块:只执行一次
构造代码块:每次调用构造方法都执行

继承

把多个类中相同的内容给提取出来定义到一个类中。
格式:
class 子类名 extends 父类名 {}

class Person {
    
    public void eat() {
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }
}

class Student extends Person {
    }

class Teacher extends Person {
    }

class ExtendsDemo {
    
    public static void main(String[] args) {
        Student s = new Student();
        s.eat();
        s.sleep();
        System.out.println("-------------");

        Teacher t = new Teacher();
        t.eat();
        t.sleep();
    }
}

继承的好处:
A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类之间产生了关系,是多态的前提
继承的弊端:
A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
原则:低耦合,高内聚。
耦合:类与类的关系
内聚:自己完成某件事情的能力
B:打破了封装性

Java中继承的特点:

  • A:Java只支持单继承,不支持多继承。有些语言是支持多继承,格式:extends 类1,类2,…
  • B:Java支持多层继承(继承体系)

继承的注意事项:

  • A:子类只能继承父类所有非私有的成员(成员方法和成员变量)
  • B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
  • C:不要为了部分功能而去继承

什么时候考虑使用继承
如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
继承其实体现的是一种关系:”is a”。

继承中成员变量的关系:

  • A:子类中的成员变量和父类中的成员变量名称不一样
  • B:子类中的成员变量和父类中的成员变量名称一样

在子类方法中访问一个变量的查找顺序:
- a:在子类方法的局部范围找,有就使用
- b:在子类的成员范围找,有就使
- c:在父类的成员范围找,有就使用
- d:如果还找不到,就报错。

this和super的区别
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)

用法
A:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量

B:调用构造方法
this(…) 调用本类的构造方法
super(…) 调用父类的构造方法

C:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法

子父类中,成员的特点体现:
1.成员变量
当本类的成员和局部变量同名用this区分
当子父类中的成员变量同名时用super区分父类
this和super的用法很相似
this:代表一个本类对象的引用
super:代表一个父类空间

2成员函数
当子父类中出现成员函数一模一样的情况,会运行子类的函数
这种现象,称为覆盖操作,这是函数在子父类中的特征
函数两个特性:
重载,同一个类中
覆盖,子类中。覆盖也称为重写,覆写。

覆盖的注意事项:
1.子类方法覆盖父类方法时,子类全选必须权限大于等于父类
2.静态只能覆盖静态,或被静态覆盖
3.构造函数
在子类构造对象时,发现,访问子类构造函数时,父类也运行了。
原因是:在子类的构造函数中第一行有一个默认的隐式语句,super()
super()调用的就是父类中的空参构造函数。

class Fu {
    
    Fu() {
        System.out.println("Fu run");
    }

    Fu(int num) {
        System.out.println("Fu:" + num);
    }
}

class Zi extends Fu {
    
    Zi() {
        // super();隐式语句,调用的就是父类中的空参构造函数
        System.out.println("Zi run");
    }

    Zi(int num) {
        // super();这里也有隐式语句super()
        // 用super明确调用父类中的那个构造方法
        super(num);
        this();
        // this和super只能有一个在第一行,this调用了本类中空参构造方法,空参构造方法中也会有一个隐式super()语句。
        // 所以子类中要保证会有一个构造方法访问到父类的构造方法
        System.out.println("Zi:" + num);
    }
}

class ExtendsDemo {
    
    public static void main(String[] args) {
        new Zi();
        new Zi(5);
    }
}

final

可以修饰类,方法,变量
特点:
final可以修饰类,该类不能被继承。
final可以修饰方法,该方法不能被重写。(覆盖,复写)
final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。

常量:
A:字面值常量
“hello”,10,true
B:自定义常量
final int x = 10;

class Fu {
    
    public int num = 10;
    public final int num2 = 20;
}

class Zi extends Fu {
    
    // Zi中的show()无法覆盖Fu中的show()
    public void show() {
        num = 100;
        System.out.println(num);

        //无法为最终变量num2分配值
        //num2 = 200;
        System.out.println(num2);
    }
}

class FinalDemo {
    
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show();
    }
}

final修饰变量的初始化时机
A:被final修饰的变量只能赋值一次。
B:在构造方法完毕前。(非静态的常量)

多态

同一个对象在不同时刻体现出来的不同状态。
多态的前提:
- A:有继承或者实现关系。
- B:有方法重写。
- C:有父类或者父接口引用指向子类对象。

多态的分类
具体类多态

class Fu {
    }
class Zi extends Fu {
    }
Fu f = new Zi();

抽象类多态

abstract class Fu {
    }
class Zi extends Fu {
    }
Fu f = new Zi();

接口多态

interface Fu {
    }
class Zi implements Fu {
    }
Fu f = new Zi();

多态中的成员访问特点
A:成员变量
编译看左边,运行看左边
B:构造方法
子类的构造都会默认访问父类构造
C:成员方法
编译看左边,运行看右边
D:静态方法
编译看左边,运行看左边

为什么?
因为成员方法有重写。

class Fu {
    public int num = 100;

    public void show() {
        System.out.println("show Fu");
    }

    public static void function() {
        System.out.println("function Fu");
    }
}

class Zi extends Fu {
    public int num = 1000;
    public int num2 = 200;

    public void show() {
        System.out.println("show Zi");
    }

    public void method() {
        System.out.println("method zi");
    }

    public static void function() {
        System.out.println("function Zi");
    }
}

class DuoTaiDemo {
    public static void main(String[] args) {
        //要有父类引用指向子类对象。
        //父 f =  new 子();
        Fu f = new Zi();
        System.out.println(f.num);
        //找不到符号
        //System.out.println(f.num2);

        f.show();
        //找不到符号
        //f.method();
        f.function();
    }
}

多态的好处:
- A:提高代码的维护性(继承体现)
- B:提高代码的扩展性(多态体现)

多态的弊端:
父不能使用子的特有功能。
现象:子可以当作父使用,父不能当作子使用。

多态中的转型
- A:向上转型:从子到父
- B:向下转型:从父到子

class Animal {
    
    public void eat(){}
}

class Dog extends Animal {
    
    public void eat() {}

    public void lookDoor() {

    }
}

class Cat extends Animal {
    
    public void eat() {

    }

    public void playGame() {

    }
}

class DuoTaiDemo5 {
    
    public static void main(String[] args) {
        //内存中的是狗
        Animal a = new Dog();
        Dog d = (Dog)a;

        //内存中是猫
        a = new Cat();
        Cat c = (Cat)a;

        //内存中是猫
        Dog dd = (Dog)a; //ClassCastException
    }
}

抽象类

把多个共性的东西提取到一个类中,这是继承的做法。
但是呢,这多个共性的东西,在有些时候,方法声明一样,但是方法体。
也就是说,方法声明一样,但是每个具体的对象在具体实现的时候内容不一样。
所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。
而一个没有具体的方法体的方法是抽象的方法。
在一个类中如果有抽象方法,该类必须定义为抽象类。

抽象类的特点
A:抽象类和抽象方法必须用关键字abstract修饰
B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
C:抽象类不能实例化
D:抽象类的子类
a:是一个抽象类。
b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。

抽象类的成员特点:
A:成员变量
有变量,有常量
B:构造方法
有构造方法
C:成员方法
有抽象,有非抽象

abstract class Fu {
    

    static abstract void show();

    public static void method() {
        System.out.println("method");
    }
}

class Zi extends Fu {
    
    public void show() {}
}

class AbstractDemo3 {
    
    public static void main(String[] args) {
        Fu.method();
    }
}

接口

比如:猫钻火圈,狗跳高等功能,不是动物本身就具备的,
是在后面的培养中训练出来的,这种额外的功能,java提供了接口表示。

接口的特点:
A:接口用关键字interface修饰
interface 接口名 {}
B:类实现接口用implements修饰
class 类名 implements 接口名 {}
C:接口不能实例化
D:接口的实现类
a:是一个抽象类。
b:是一个具体类,这个类必须重写接口中的所有抽象方法。

//定义动物培训接口
interface AnimalTrain {
    
    public abstract void jump();
}

//抽象类实现接口
abstract class Dog implements AnimalTrain {
    
}

//具体类实现接口
class Cat implements AnimalTrain {
    
    public void jump() {
        System.out.println("猫可以跳高了");
    }
}

class InterfaceDemo {
    
    public static void main(String[] args) {
        //AnimalTrain是抽象的; 无法实例化
        //AnimalTrain at = new AnimalTrain();
        //at.jump();

        AnimalTrain at = new Cat();
        at.jump();
    }
}

接口成员特点
成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。

构造方法:接口没有构造方法。

成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。

所有的类都默认继承自一个类:Object。
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。

类与类:
继承关系,只能单继承,可以多层继承。

类与接口:
实现关系,可以单实现,也可以多实现。
并且还可以在继承一个类的同时实现多个接口。

接口与接口:
继承关系,可以单继承,也可以多继承。

interface Father {
    
    public abstract void show();
}

interface Mother {
    
    public abstract void show2();
}

interface Sister extends Father,Mother {
    

}

//class Son implements Father,Mother //多实现
class Son extends Object implements Father,Mother {
    
    public void show() {
        System.out.println("show son");
    }

    public void show2() {
        System.out.println("show2 son");
    }
}

class InterfaceDemo3 {
    
    public static void main(String[] args) {
        //创建对象
        Father f = new Son();
        f.show();

        Mother m = new Son();
        m.show2();
    }
}

抽象类和接口的区别

A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象

接口:
成员变量:只可以常量
成员方法:只可以抽象

B:关系区别
类与类
继承,单继承

类与接口
实现,单实现,多实现

接口与接口
继承,单继承,多继承

设计理念区别
抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

形式参数和返回值

(1)形式参数:
类名:需要该类的对象
抽象类名:需要该类的子类对象
接口名:需要该接口的实现类对象

(2)返回值类型:
类名:返回的是该类的对象
抽象类名:返回的是该类的子类对象
接口名:返回的是该接口的实现类的对象

(3)链式编程
对象.方法1().方法2()…….方法n();

这种用法:其实在方法1()调用完毕后,应该一个对象;
方法2()调用完毕后,应该返回一个对象。
方法n()调用完毕后,可能是对象,也可以不是对象。

内部类

概述:
把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。

内部类的访问特点:
A:内部类可以直接访问外部类的成员,包括私有。
B:外部类要访问内部类的成员,必须创建对象。

内部类位置
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。

成员内部类:
如何直接访问内部类的成员。
外部类名.内部类名 对象名 = 外部类对象.内部类对象;

成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意:静态内部类访问的外部类数据必须用静态修饰。

class Outer {
    private int num = 10;
    private static int num2 = 100;

    //内部类用静态修饰是因为内部类可以看出是外部类的成员
    public static class Inner {
        public void show() {
            System.out.println(num2);
        }

        public static void show2() {
            System.out.println(num2);
        }       
    }
}

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

        Outer.Inner oi = new Outer.Inner();
        oi.show();
        oi.show2();

        //show2()的另一种调用方式
        Outer.Inner.show2();
    }
}

局部内部类
A:可以直接访问外部类的成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能

局部内部类访问局部变量的注意事项
A:局部内部类访问局部变量必须用final修饰
B:为什么呢?
局部变量是随着方法的调用而调用,随着调用完毕而消失。而堆内存的内容并不会立即消失。所以,我们加final修饰。加入final修饰后,这个变量就成了常量。

class Outer {
    private int num  = 10;

    public void method() {
        //int num2 = 20;
        //final int num2 = 20;
        class Inner {
            public void show() {
                System.out.println(num);
                //从内部类中访问本地变量num2; 需要被声明为最终类型
                System.out.println(num2);//20
            }
        }

        //System.out.println(num2);

        Inner i = new Inner();
        i.show();
    }
}

class InnerClassDemo5 {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method();
    }
}

匿名内部类
就是内部类的简化写法。

前提:存在一个类或者接口
这里的类可以是具体类也可以是抽象类。

格式:
new 类名或者接口名(){
重写方法;
}

本质
是一个继承了该类或者实现了该接口的子类匿名对象。

interface Inter {
    public abstract void show();
    public abstract void show2();
}

class Outer {
    public void method() {
        Inter i = new Inter() { //多态
            public void show() {
                System.out.println("show");
            }

            public void show2() {
                System.out.println("show2");
            }
        };

        i.show();
        i.show2();
    }
}

class InnerClassDemo6 {
    public static void main(String[] args) {
        Outer o = new Outer();
        o.method();
    }
}

总结

面向对象是Java最重要的内容,以后所有的知识都是围绕着面向对象展开的,可以说,没有面向对象,以后学习的功能都无法使用。

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Sherlock_Li/article/details/48108513

智能推荐

从零开始搭建Hadoop_创建一个hadoop项目-程序员宅基地

文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目

心脏滴血漏洞HeartBleed CVE-2014-0160深入代码层面的分析_heartbleed代码分析-程序员宅基地

文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析

java读取ofd文档内容_ofd电子文档内容分析工具(分析文档、签章和证书)-程序员宅基地

文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat

基于FPGA的数据采集系统(一)_基于fpga的信息采集-程序员宅基地

文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集

微服务 spring cloud zuul com.netflix.zuul.exception.ZuulException GENERAL-程序员宅基地

文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception

邻接矩阵-建立图-程序员宅基地

文章浏览阅读358次。1.介绍图的相关概念  图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为:  G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图

随便推点

MDT2012部署系列之11 WDS安装与配置-程序员宅基地

文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc

python--xlrd/xlwt/xlutils_xlutils模块可以读xlsx吗-程序员宅基地

文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗

关于新版本selenium定位元素报错:‘WebDriver‘ object has no attribute ‘find_element_by_id‘等问题_unresolved attribute reference 'find_element_by_id-程序员宅基地

文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver

DOM对象转换成jQuery对象转换与子页面获取父页面DOM对象-程序员宅基地

文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象

什么是算法?-程序员宅基地

文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法

【网络安全】网络安全的标准和规范_网络安全标准规范-程序员宅基地

文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范