Java基础(面向对象三——多态、内部类)
来源:互联网 发布:java 打印map 键值对 编辑:程序博客网 时间:2024/05/11 17:05
一、多态
定义:事物存在的多种表现形式
例如:动物中猫和狗
猫这个对象对应的类型是猫类型 猫 m = new 猫();
而猫是动物中的一种,所以也可以把猫称为动物,也就是说让父类引用指向子类对象 动物 d = new 猫();
多态的表现形式:
- 父类的引用指向了子类对象
- 父类的引用也可以接收该父类类型的对象
多态的前提:
- 必须类与类之间存在关系,要么继承要么实现
- 要存在覆盖(复写)
多态的好处:
多态的出现大大的提高了程序的扩展性
多态的弊端:
多态虽然提高了程序的扩展性,但是只能使用父类的引用访问父类的成员
多态的应用:
多态的出现代码中的特点:
在多态中成员函数的特点(非静态)
在编译时期:参阅引用型变量是否有调用的方法,如果有,则编译通过
在运行时期,参阅对象所在的类中是否有调用的方法简单一句话:编译看左边,运行看右边
白话:就是当父类引用指向子类对象时,如果调用的方法父类中有,就编译通过,没有就报错,如果有再看子类中是否重写该方法,如果重写,不言而喻肯定运行的是子类中的内容
在多态中成员变量的特点:无论编译还是运行,都参考左边
在使用多态调用成员变量时,如果父类和子类中拥有相同名称的成员变量时,左边为父类,那么调用的就是父类中的成员变量,如果左边为子类,那么就调用子类中的成员变量
在多态中静态成员的特点:无论编译还是运行都参考左边
一样道理,静态只要类一加载就存在了,是不需要使用对象的,所以谁调用就运行谁
多态的表现形式:
abstract class Animal{ //定义为抽象方法,要求子类必须实现,因为只要是动物,都具备吃的行为 public 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 kanHome(){ System.out.println("狗看家"); }}class DuoTaiDemo{ public static void main(String[] args) { /* Cat c = new Cat(); c.eat(); Dog d = new Dog(); d.eat(); */ /* 发现这样写会比较麻烦,因为每出现一种动物想要调用该动物的eat()方法都要建立该动物对象,有没有简单一点的方法呢? 因为不管是猫还是狗都是动物,都具备eat()方法,那我能不能直接让动物指向自己的子类呢?因为子类复写了父类中的方法,当使用父类引用指向子类对象调用父类方法时,调用的还是子类的方法 */ function(new Cat()); function(new Dog()); public void function(Animal a){ //Adimal a = new Cat(); 向上转型 a.eat(); } /* 但是发现这样写完之后发现没法调用子类特有的方法了,因为动物中是没有子类特有的行为的,怎么办呢? 因为动物不具备猫和狗特有的行为,那么我们能不能使用子类去调用自己特有的方法呢? 向下转型: public void function(Animal a){ a.eat(); if(a instanceof Cat){ //判断传入的对象类型 Cat c = (Cat) a; //把动物强制转换成猫 c.catchMouse(); } else if(a instanceof Dog){ Dog d = (Dog) a; d.kanHome(); } } */ }}
二、内部类
定义:将一个类定义在另一个类的里面,对里面那个 类就称为内部类(内置类,嵌套类),一个类可以定义多个内部类。
内部类访问规则:
1、内部类可以直接访问外部类的成员,包括私有化成员
2、外部类要访问内部类必须要创建内部类对象
访问格式:
1、当内部类定义在外部类的成员位置上时,并且非私有化,
注:当内部类定义在外部类的成员位置上时,是可以被private static成员修饰符修饰的,被static修饰的内部类只能访问外部类中的静态成员
1.1、在本类内部访问内部类
class Demo{//外部类成员变量int num = 5;//内部类class Inner{//内部类成员函数public void show(){System.out.println("调用内部类show方法");}}//外部类成员函数public void function(){//创建内部类对象调用内部类方法Inner in = new Inner();in.show();}}注:如果内部类中有同名称的变量,在内部类中调用外部类成员变量时,则运行的是内部类中成员变量的值(其实就是省略了this),而当要访问外部类成员变量时,则需要标识,格式:外部类.this.要调用的变量名
1.2、在外部其他类中访问内部类
//在外部其他类中访问内部类class Outer{int x = 5;//内部类class Inner{public void show(){System.out.println("调用内部类方法");}}public void function(){System.out.println("Outer的方法");}}class Demo{public static void main(String[] args) {//在其他类中直接访问内部类/*因为不确定到底有几个Inner类,所以创建内部类对象时要指明要创建的内部类格式 外部类.内部类 变量名 = new 外部类类名().new 内部类类名();*/Outer.Inner in = new Outer().new Inner();}}注:如果内部类中有同名称的变量,在其他外部类中调用内部类成员变量时,如果内部类中有该变量并没有私有化,则运行的是内部类中成员变量的值,如果没有,则运行该内部类所在的外部类中的没有私有化的成员变量的值
2、当内部类定义在成员位置上并被private或static所修饰时
注:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的2.1、在外部其他类中,直接访问static内部类的非静态成员
class Outer{int x = 5;//静态内部类static class Inner{//内部类中的非静态成员方法public void show(){System.out.println("调用内部类方法");}}public void function(){System.out.println("Outer的方法");}}class Demo{public static void main(String[] args) {//在其他类中直接访问静态内部类中的非静态方法new Outer.Inner().show();}}2.2、在外部其他类中,直接访问static内部类的静态成员class Outer{int x = 5;//静态内部类static class Inner{//内部类中的静态成员方法public static void show(){System.out.println("调用内部类方法");}}public void function(){System.out.println("Outer的方法");}}class Demo{public static void main(String[] args) {//在其他类中直接访问静态内部类中的静态方法Outer.Inner().show();}}3、当内部类定义在局部位置上时
1、不可以被成员的修饰符所修饰
2、可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量class Outer{int num = 5;//外部类成员函数public void function(){int x = 3;/*内部类定义在局部位置上,不可以被static、private所修饰,此时可以访问成员变量num,但是不可以访问局部变量x,因为x没有被 final 所修饰如果代码改为:public void function(final int x){class Inner{public void show(){System.out.println("调用内部类方法");}}}就可以访问了,这样写有一个特点,就是调用function并传参后x的值就固定了,不可以在进行赋值操作了*/class Inner{public void show(){System.out.println("调用内部类方法");}}}}什么时候使用内部类呢?
当描述事物,而事物的内部还有事物,该事物用内部类来描述,因为内部事物在使用外部事物的内容
三、匿名内部类
定义:其实就是内部类的简写格式
定义匿名内部类的前提:内部类必须是继承一个类或者实现接口
匿名内部类的格式:new 父类或者接口(){定义子类的内容}
注:1、其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象
2、匿名内部类中定义的方法最好不要超过3个
interface AbsDemo{public void show();}class Outer{//有名内部类/*class Inner implements AbsDemo{public void show(){System.out.println("有名内部类");}}public void function(){AbsDemo ab = new Inner();ab.show();}*///匿名内部类public void function(){new AbsDemo(){public void show(){System.out.println("匿名内部类");}}.show();/*因为是匿名内部类,所以是没有名字的,只能通过创捷父类或接口来建立子类对象,完成复写*/}}class {public static void main(String[] args) {System.out.println("Hello World!");}}小练习://根据已有代码补全程序,要求使用匿名函数/*已有代码:interface Inner{public abstract void method();}class Test{public static function(){}}class Demo{public static void main(String[] args) {Test.function().method();}}*/class Demo{public static void main(String[] args) {//Test.function():Test类中有一个静态的方法function。//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象。//因为只有是Inter类型的对象,才可以调用method方法。Test.function().method();}}//使用匿名对象interface Inner{public abstract void method();}class Test{public static Inner function(){return new Inner(){public void method(){System.out.println("重写了方法");};}}}/*不使用匿名对象interface Inner{public abstract void method();}class Test{class Util implements Inner{public void method(){System.out.println("重写了方法");}}public static Inner function(){return new Util();}}}*/
- Java基础(面向对象三——多态、内部类)
- 黑马程序员——java基础----面向对象(三)内部类
- 【java基础】——java面向对象(下)—多态、内部类、异常、包
- 黑马程序员——java面向对象(三)多态、内部类、包
- Java基础(七)——面向对象_多态、内部类、其它
- 黑马程序员——java基础(面向对象)抽象、接口、内部类
- JAVA面向对象基础:内部类
- Java面向对象基础--内部类
- 黑马程序员---Java基础---面向对象:多态、内部类、异常
- java基础3--面向对象(上)(内部类)
- Java基础--面向对象(内部类、异常)
- Java-面向对象(基础编)--内部类
- 面向对象基础(六)[内部类]
- 面向对象基础(内部类)
- 黑马程序员 java学习笔记——面向对象3:多态(含内部类)
- 黑马程序员——java-面向对象二(继承,多态,抽象,接口,包,内部类)
- Java基础——面向对象——继承、抽象类、接口、多态、包、内部类、异常等
- Java面向对象06-多态,内部类
- js实现网页防止被iframe框架嵌套及几种location.href的区别
- mac 下的 git 安装
- day07-servletのPPT学习总结
- 通过wifi连接调试Android程序
- 鼠标悬停内容移动切换效果
- Java基础(面向对象三——多态、内部类)
- Linux 下交叉编译环境设置
- UVA - 10154 Weights and Measures
- Linux vmstat命令实战详解
- 栈的逆序算法
- Swift 运算符重载
- android平板上的GridView视图缓存优化
- day07-Servletの代码总结
- TCP慢启动、拥塞避免、快速重传、快速恢复