Java笔记(10):面向对象--内部类
Posted 花醉红尘
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java笔记(10):面向对象--内部类相关的知识,希望对你有一定的参考价值。
1、类名作为形式参数
1 /* 2 形式参数: 3 基本类型 4 引用类型 5 类名:(匿名对象的时候其实我们已经讲过了) 需要的是该类的对象 6 抽象类: 7 接口 8 */ 9 class Student { 10 public void study() { 11 System.out.println("Good Good Study,Day Day Up"); 12 } 13 } 14 15 class StudentDemo { 16 public void method(Student s) { //ss; ss = new Student(); Student s = new Student(); 17 s.study(); 18 } 19 } 20 21 class StudentTest { 22 public static void main(String[] args) { 23 //需求:我要测试Student类的study()方法 24 Student s = new Student(); 25 s.study(); 26 System.out.println("----------------"); 27 28 //需求2:我要测试StudentDemo类中的method()方法 29 StudentDemo sd = new StudentDemo(); 30 Student ss = new Student(); 31 sd.method(ss); 32 System.out.println("----------------"); 33 34 //匿名对象用法 35 new StudentDemo().method(new Student()); 36 } 37 }
2、抽象类名作为形式参数
1 /* 2 形式参数: 3 基本类型 4 引用类型 5 类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象 6 抽象类:需要的是该抽象的类子类对象 7 接口 8 */ 9 abstract class Person { 10 public abstract void study(); 11 } 12 13 class PersonDemo { 14 public void method(Person p) {//p; p = new Student(); Person p = new Student(); //多态 15 p.study(); 16 } 17 } 18 19 //定义一个具体的学生类 20 class Student extends Person { 21 public void study() { 22 System.out.println("Good Good Study,Day Day Up"); 23 } 24 } 25 26 class PersonTest { 27 public static void main(String[] args) { 28 PersonDemo pd = new PersonDemo(); 29 Person p = new Student(); 30 pd.method(p); 31 } 32 }
3、接口名作为形式参数
1 /* 2 形式参数: 3 基本类型(太简单,不是我今天要讲解的) 4 引用类型 5 类名:(匿名对象的时候其实我们已经讲过了)需要的是该类的对象 6 抽象类:需要的是该抽象的类子类对象 7 接口:需要的是该接口的实现类对象 8 */ 9 //定义一个爱好的接口 10 interface Love { 11 public abstract void love(); 12 } 13 14 class LoveDemo { 15 public void method(Love l) { //l; l = new Teacher(); Love l = new Teacher(); 多态 16 l.love(); 17 } 18 } 19 20 //定义具体类实现接口 21 class Teacher implements Love { 22 public void love() { 23 System.out.println("老师爱学生,爱Java,爱林青霞"); 24 } 25 } 26 27 class TeacherTest { 28 public static void main(String[] args) { 29 //需求:我要测试LoveDemo类中的love()方法 30 LoveDemo ld = new LoveDemo(); 31 Love l = new Teacher(); 32 ld.method(l); 33 } 34 }
4、类名作为返回值类型
1 /* 2 返回值类型 3 基本类型:(基本类型太简单,我不准备讲解) 4 引用类型: 5 类:返回的是该类的对象 6 抽象类: 7 接口: 8 */ 9 class Student { 10 public void study() { 11 System.out.println("Good Good Study,Day Day Up"); 12 } 13 } 14 15 class StudentDemo { 16 public Student getStudent() { 17 //Student s = new Student(); 18 //Student ss = s; 19 20 //Student s = new Student(); 21 //return s; 22 return new Student(); 23 } 24 } 25 26 class StudentTest2 { 27 public static void main(String[] args) { 28 //需求:我要使用Student类中的study()方法 29 //但是,这一次我的要求是,不要直接创建Student的对象 30 //让你使用StudentDemo帮你创建对象 31 StudentDemo sd = new StudentDemo(); 32 Student s = sd.getStudent(); //new Student(); Student s = new Student(); 33 s.study(); 34 } 35 }
5、抽象类名作为返回值类型
1 /* 2 返回值类型 3 基本类型:(基本类型太简单,我不准备讲解) 4 引用类型: 5 类:返回的是该类的对象 6 抽象类:返回的是该抽象类的子类对象 7 接口: 8 */ 9 abstract class Person { 10 public abstract void study(); 11 } 12 13 class PersonDemo { 14 public Person getPerson() { 15 //Person p = new Student(); 16 //return p; 17 18 return new Student(); 19 } 20 } 21 22 class Student extends Person { 23 public void study() { 24 System.out.println("Good Good Study,Day Day Up"); 25 } 26 } 27 28 class PersonTest2 { 29 public static void main(String[] args) { 30 //需求:我要测试Person类中的study()方法 31 PersonDemo pd = new PersonDemo(); 32 Person p = pd.getPerson(); //new Student(); Person p = new Student(); 多态 33 p.study(); 34 } 35 }
6、接口名作为返回值类型
1 /* 2 返回值类型 3 基本类型:(基本类型太简单,我不准备讲解) 4 引用类型: 5 类:返回的是该类的对象 6 抽象类:返回的是该抽象类的子类对象 7 接口:返回的是该接口的实现类的对象 8 */ 9 //定义一个爱好的接口 10 interface Love { 11 public abstract void love(); 12 } 13 14 class LoveDemo { 15 public Love getLove() { 16 //Love l = new Teacher(); 17 //return l; 18 19 return new Teacher(); 20 } 21 } 22 23 //定义具体类实现接口 24 class Teacher implements Love { 25 public void love() { 26 System.out.println("老师爱学生,爱Java,爱林青霞"); 27 } 28 } 29 30 class TeacherTest2 { 31 public static void main(String[] args) { 32 //如何测试呢? 33 LoveDemo ld = new LoveDemo(); 34 Love l = ld.getLove(); //new Teacher(); Love l = new Teacher(); 多态 35 l.love(); 36 } 37 }
7、链式编程
1 /* 2 链式编程。 3 每次调用完毕方法后,返回的是一个对象。 4 */ 5 class Student { 6 public void study() { 7 System.out.println("Good Good Study,Day Day Up"); 8 } 9 } 10 11 class StudentDemo { 12 public Student getStudent() { 13 return new Student(); 14 } 15 } 16 17 class StudentTest3 { 18 public static void main(String[] args) { 19 //如何调用的呢? 20 StudentDemo sd = new StudentDemo(); 21 //Student s = sd.getStudent(); 22 //s.study(); 23 24 //大家注意了 25 sd.getStudent().study(); 26 } 27 }
8、包的概述及编译运行
1 /* 2 包: 3 A:其实就是文件夹 4 B:作用 5 a:把相同的类名放到不同的包中 6 b:对类进行分类管理 7 8 举例: 9 学生:增加,删除,修改,查询 10 老师:增加,删除,修改,查询 11 ... 12 13 方案1:按照功能分 14 cn.itcast.add 15 AddStudent 16 AddTeacher 17 cn.itcast.delete 18 DeleteStudent 19 DeleteTeacher 20 cn.itcast.update 21 UpdateStudent 22 UpdateTeacher 23 cn.itcast.find 24 FindStudent 25 FindTeacher 26 27 方案2:按照模块分 28 cn.itcast.teacher 29 AddTeacher 30 DeleteTeacher 31 UpdateTeacher 32 FindTeacher 33 cn.itcast.student 34 AddStudent 35 DeleteStudent 36 UpdateStudent 37 FindStudent 38 39 包的定义 40 package 包名; 41 多级包用.分开即可 42 43 44 注意事项: 45 A:package语句必须是程序的第一条可执行的代码 46 B:package语句在一个java文件中只能有一个 47 C:如果没有package,默认表示无包名 48 49 带包的编译和运行: 50 A:手动式 51 a:编写一个带包的java文件。 52 b:通过javac命令编译该java文件。 53 c:手动创建包名。 54 d:把b步骤的class文件放到c步骤的最底层包 55 e:回到和包根目录在同一目录的地方,然后运行 56 带包运行。 57 58 B:自动式 59 a:编写一个带包的java文件。 60 b:javac编译的时候带上-d即可 61 javac -d . HelloWorld.java 62 c:回到和包根目录在同一目录的地方,然后运行 63 带包运行。 64 */ 65 package cn.itcast; 66 67 class HelloWorld { 68 public static void main(String[] args) { 69 System.out.println("HelloWorld"); 70 } 71 }
9、不同包间的访问
1 /* 2 Demo类,求和 3 */ 4 package com.liuyi; 5 6 public class Demo { 7 public int sum(int a,int b) { 8 return a + b; 9 } 10 }
1 /* 2 Test类,测试 3 4 导包: 5 格式:import 包名; 6 这种方式导入是到类的名称。 7 注意:我们用谁就导谁。 8 9 面试题: 10 package,import,class有没有顺序关系? 11 有。 12 package > import > class 13 14 Package:只能有一个 15 import:可以有多个 16 class:可以有多个,以后建议是一个 17 */ 18 package cn.itcast; 19 20 import com.liuyi.Demo; 21 22 class Test { 23 public static void main(String[] args) { 24 //Demo d = new Demo(); 25 /* 26 com.liuyi.Demo d = new com.liuyi.Demo(); 27 System.out.println(d.sum(10,20)); 28 29 com.liuyi.Demo d2 = new com.liuyi.Demo(); 30 System.out.println(d2.sum(10,20)); 31 32 com.liuyi.Demo d3 = new com.liuyi.Demo(); 33 System.out.println(d3.sum(10,20)); 34 35 com.liuyi.Demo d4 = new com.liuyi.Demo(); 36 System.out.println(d4.sum(10,20)); 37 */ 38 39 Demo d = new Demo(); 40 System.out.println(d.sum(10,20)); 41 } 42 } 43 44 /* 45 第一个问题:找不到Demo 46 47 第二个问题:程序包com.liuyi不存在 48 49 第三个问题: Demo在com.liuyi中不是公共的; 无法从外部程序包中对其进行访问 50 */
10、修饰符的概述和总结
1 /* 2 权限修饰符: 3 本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类) 4 private Y 5 默认 Y Y 6 protected Y Y Y 7 public Y Y Y Y 8 */ 9 package com.liuyi; 10 11 public class Father { 12 private void show() { 13 System.out.println("show"); 14 } 15 16 void show2() { 17 System.out.println("show2"); 18 } 19 20 protected void show3() { 21 System.out.println("show3"); 22 } 23 24 public void show4() { 25 System.out.println("show4"); 26 } 27 28 public static void main(String[] args) { 29 Father f = new Father(); 30 f.show(); 31 f.show2(); 32 f.show3(); 33 f.show4(); 34 } 35 }
10、常见修饰符的使用
1 /* 2 修饰符: 3 权限修饰符:private,默认的,protected,public 4 状态修饰符:static,final 5 抽象修饰符:abstract 6 7 类: 8 权限修饰符:默认修饰符,public 9 状态修饰符:final 10 抽象修饰符:abstract 11 12 用的最多的就是:public 13 14 成员变量: 15 权限修饰符:private,默认的,protected,public 16 状态修饰符:static,final 17 18 用的最多的就是:private 19 20 构造方法: 21 权限修饰符:private,默认的,protected,public 22 23 用的最多的就是:public 24 25 成员方法: 26 权限修饰符:private,默认的,protected,public 27 状态修饰符:static,final 28 抽象修饰符:abstract 29 30 用的最多的就是:public 31 32 除此以外的组合规则: 33 成员变量:public static final 34 成员方法:public static 35 public abstract 36 public final 37 38 */ 39 //此处不允许使用修饰符private 40 //此处不允许使用修饰符protected 41 //此处不允许使用修饰符static 42 public class Demo { 43 //成员变量 44 private int x = 10; 45 int y = 20; 46 protected int z = 30; 47 public int a = 40; 48 public final int b = 50; 49 public static int c = 60; 50 public static final int d = 70; 51 //此处不允许使用修饰符abstract 52 //abstract int e = 80; 53 54 //构造方法 55 private Demo(){} 56 57 Demo(String name){} 58 59 protected Demo(String name,int age) {} 60 61 public Demo(String name,int age,String address) {} 62 63 //此处不允许使用修饰符static 64 //public static Demo(){} 65 //此处不允许使用修饰符final 66 //public final Demo() {} 67 //此处不允许使用修饰符abstract 68 //public abstract Demo(){} 69 70 //成员方法 71 //static void show() {} 72 //abstract void show(); 73 //final void show(){} 74 }
11、内部类概述
1 /* 2 内部类概述: 3 把类定义在其他类的内部,这个类就被称为内部类。 4 举例:在类A中定义了一个类B,类B就是内部类。 5 6 内部的访问特点: 7 A:内部类可以直接访问外部类的成员,包括私有。 8 B:外部类要访问内部类的成员,必须创建对象。 9 10 */ 11 class Outer { 12 private int num = 10; 13 14 class Inner { 15 public void show() { 16 System.out.println(num); 17 } 18 } 19 20 public void method() { 21 //找不到符号 22 //show(); 23 24 Inner i = new Inner(); 25 i.show(); 26 } 27 28 } 29 30 class InnerClassDemo { 31 public static void main(String[] args) { 32 33 } 34 }
12、内部类分类及成员内部类的直接使用
1 /* 2 内部类位置 3 成员位置:在成员位置定义的类,被称为成员内部类。 4 局部位置:在局部位置定义的类,被称为局部内部类。 5 6 7 成员位置:在成员位置定义的类,被称为成员内部类。 8 9 */ 10 class Outer { 11 private int num = 10; 12 13 //成员位置 14 /* 15 class Inner { 16 17 } 18 */ 19 20 21 22 public void method() { 23 //局部位置 24 class Inner { 25 26 } 27 } 28 } 29 30 class InnerClassDemo2 { 31 public static void main(String[] args) { 32 33 } 34 }
1 /* 2 成员内部类: 3 如何直接访问内部类的成员。 4 外部类名.内部类名 对象名 = 外部类对象.内部类对象; 5 */ 6 class Outer { 7 private int num = 10; 8 9 class Inner { 10 public void show() { 11 System.out.println(num); 12 } 13 } 14 } 15 16 class InnerClassDemo3 { 17 public static void main(String[] args) { 18 //需求:我要访问Inner类的show()方法 19 //Inner i = new Inner(); 20 //i.show(); 21 22 //格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象; 23 Outer.Inner oi = new Outer().new Inner(); 24 oi.show(); 25 } 26 }
13、成员内部类的常见修饰符
1 /* 2 成员内部类的修饰符: 3 private 为了保证数据的安全性 4 static 为了方便访问数据 5 注意:静态内部类访问的外部类数据必须用静态修饰。 6 7 案例:我有一个人(人有身体,身体内有心脏。) 8 9 class Body { 10 private class Heart { 11 public void operator() { 12 System.out.println("心脏搭桥"); 13 } 14 } 15 16 public void method() { 17 if(如果你是外科医生) { 18 Heart h = new Heart(); 19 h.operator(); 20 } 21 } 22 } 23 24 按照我们刚才的讲解,来使用一下 25 Body.Heart bh = new Body().new Heart(); 26 bh.operator(); 27 //加了private后,就不能被访问了,那么,怎么玩呢? 28 Body b = new Body(); 29 b.method(); 30 */ 31 class Outer { 32 private int num = 10; 33 private static int num2 = 100; 34 35 //内部类用静态修饰是因为内部类可以看出是外部类的成员 36 public static class Inner { 37 public void show() { 38 //System.out.println(num); 39 System.out.println(num2); 40 } 41 42 public static void show2() { 43 //System.out.println(num); 44 System.out.println(num2); 45 } 46 } 47 } 48 49 class InnerClassDemo4 { 50 public static void main(String[] args) { 51 //使用内部类 52 // 限定的新静态类 53 //Outer.Inner oi = new Outer().new Inner(); 54 //oi.show(); 55 //oi.show2(); 56 57 //成员内部类被静态修饰后的访问方式是: 58 //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名(); 59 Outer.Inner oi = new Outer.Inner(); 60 oi.show(); 61 oi.show2(); 62 63 //show2()的另一种调用方式 64 Outer.Inner.show2(); 65 } 66 }
练习:
1 /* 2 面试题: 3 要求请填空分别输出30,20,10。 4 5 注意: 6 1:内部类和外部类没有继承关系。 7 2:通过外部类名限定this对象 8 Outer.this 9 */ 10 class Outer { 11 public int num = 10; 12 class Inner { 13 public int num = 20; 14 public void show() { 15 int num = 30; 16 System.out.println(num); 17 System.out.println(this.num); 18 //System.out.println(new Outer().num); 19 System.out.println(Outer.this.num); 20 } 21 } 22 } 23 class InnerClassTest { 24 public static void main(String[] args) { 25 Outer.Inner oi = new Outer().new Inner(); 26 oi.show(); 27 } 28 }
14、局部内部类访问局部变量
1 /* 2 局部内部类 3 A:可以直接访问外部类的成员 4 B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能 5 6 面试题: 7 局部内部类访问局部变量的注意事项? 8 A:局部内部类访问局部变量必须用final修饰 9 B:为什么呢? 10 局部变量是随着方法的调用而调用,随着调用完毕而消失。 11 而堆内存的内容并不会立即消失。所以,我们加final修饰。 12 加入final修饰后,这个变量就成了常量。既然是常量。你消失了。 13 我在内存中存储的是数据20,所以,我还是有数据在使用。 14 */ 15 class Outer { 16 private int num = 10; 17 18 public void method() { 19 //int num2 = 20; 20 //final int num2 = 20; 21 class Inner { 22 public void show() { 23 System.out.println(num); 24 //从内部类中访问本地变量num2; 需要被声明为最终类型 25 System.out.println(num2);//20 26 } 27 } 28 29 //System.out.println(num2); 30 31 Inner i = new Inner(); 32 i.show(); 33 } 34 } 35 36 class InnerClassDemo5 { 37 public static void main(String[] args) { 38 Outer o = new Outer(); 39 o.method(); 40 } 41 }
使用反编译查看效果
15、匿名内部类的方法调用
1 /* 2 匿名内部类 3 就是内部类的简化写法。 4 5 前提:存在一个类或者接口 6 这里的类可以是具体类也可以是抽象类。 7 8 格式: 9 new 类名或者接口名(){ 10 重写方法; 11 } 12 13 本质是什么呢? 14 是一个继承了该类或者实现了该接口的子类匿名对象。 15 */ 16 interface Inter { 17 public abstract void show(); 18 public abstract void show2(); 19 } 20 21 class Outer { 22 public void method() { 23 //一个方法的时候 24 /* 25 new Inter() { 26 public void show() { 27 System.out.println("show"); 28 } 29 }.show(); 30 */ 31 32 //二个方法的时候 33 /* 34 new Inter() { 35 public void show() { 36 System.out.println("show"); 37 } 38 39 public void show2() { 40 System.out.println("show2"); 41 } 42 }.show(); 43 44 new Inter() { 45 public void show() { 46 System.out.println("show"); 47 } 48 49 public void show2() { 50 System.out.println("show2"); 51 } 52 }.show2(); 53 */ 54 55 //如果我是很多个方法,就很麻烦了 56 //那么,我们有没有改进的方案呢? 57 Inter i = new Inter() { //多态 58 public void show() { 59 System.out.println("show"); 60 } 61 62 public void show2() { 63 System.out.println("show2"); 64 } 65 }; 66 67 i.show(); 68 i.show2(); 69 } 70 } 71 72 class InnerClassDemo6 { 73 public static void main(String[] args) { 74 Outer o = new Outer(); 75 o.method(); 76 } 77 }
16、匿名内部类的应用
1 /* 2 匿名内部类在开发中的使用 3 */ 4 interface Person { 5 public abstract void study(); 6 } 7 8 class PersonDemo { 9 //接口名作为形式参数 10 //其实这里需要的不是接口,而是该接口的实现类的对象 11 public void method(Person p) { 12 p.study(); 13 } 14 } 15 16 //实现类 17 class Student implements Person { 18 public void study() { 19 System.out.println("好好学习,天天向上"); 20 } 21 } 22 23 class InnerClassTest2 { 24 public static void main(String[] args) { 25 //测试 26 PersonDemo pd = new PersonDemo(); 27 Person p = new Student(); 28 pd.method(p); 29 System.out.println("--------------------"); 30 31 //匿名内部类在开发中的使用 32 //匿名内部类的本质是继承类或者实现了接口的子类匿名对象 33 pd.method(new Person(){ 34 public void study() { 35 System.out.println("好好学习,天天向上"); 36 } 37 }); 38 } 39 }
练习:
1 /* 2 匿名内部类面试题: 3 按照要求,补齐代码 4 interface Inter { void show(); } 5 class Outer { //补齐代码 } 6 class OuterDemo { 7 public static void main(String[] args) { 8 Outer.method().show(); 9 } 10 } 11 要求在控制台输出”HelloWorld” 12 */ 13 interface Inter { 14 void show(); 15 //public abstract 16 } 17 18 class Outer { 19 //补齐代码 20 public static Inter method() { 21 //子类对象 -- 子类匿名对象 22 return new Inter() { 23 public void show() { 24 System.out.println("HelloWorld"); 25 } 26 }; 27 } 28 } 29 30 class OuterDemo { 31 public static void main(String[] args) { 32 Outer.method().show(); 33 /* 34 1:Outer.method()可以看出method()应该是Outer中的一个静态方法。 35 2:Outer.method().show()可以看出method()方法的返回值是一个对象。 36 又由于接口Inter中有一个show()方法,所以我认为method()方法的返回值类型是一个接口。 37 */ 38 } 39 }
------------
以上是关于Java笔记(10):面向对象--内部类的主要内容,如果未能解决你的问题,请参考以下文章