目录 :
24 ). 面向对象(聚集关系)
25 ). 面向对象(子父类中变量的特点)
26 ). 面向对象(子父类中函数的特点-覆盖)
27 ). 面向对象(子父类中构造函数的特点--子类实例化过程)
28 ). 面向对象(final关键字)
29 ). 面向对象(抽象类1,2)
30 ). 面向对象(抽象类练习)
31 ). 面向对象(,模板方法模型)
32). 面向对象(接口1,2)
33 ). 面向对象(接口的特点)
34 ). 面向对象(接口举例实现)
35 ). 面向对象(多态--概念)
36 ). 面向对象(多态-扩展性)
37 ). 面向对象(多态--转型)
38 ). 面向对象(多态--示例)
39 ). 面向对象(多态中成员的特点)
40 ). 面向对象(多态的主版示例)
41 ). 面向对象(多态的扩展示例)
42 ). 面向对象(Object类,equals())
43 ). 面向对象(Object类的toString())
44 ). 面向对象(内部类访问规则)
45 ).面向对象(静态内部类)
46 ). 面向对象(内部类定义原则)
47 ). 面向对象(匿名内部类)
二十四
. 面向对象(聚集关系)
1 ) . 知识点 : 依据部件之间的紧密关系的不同又分为以下三类
1.1 聚集 : has a --> 房间内有卧室,客厅,卫生间,厨房 .... : 聚集
1.2 聚合 : join a -->球队中有个球员 : 聚合
1.3 组合 : unit a - -> 身体中有心脏,手,大脑等器官... : 组合
2 ) . 理解 聚集 与 继承 :
2.1相同点 :
[1] 都允许在自己的类中加入其它类的对象去访问相应的对象、操作相关的方法。
2.2 不同点 :
[1] 继承 : is a , 指"是一个"的意思,理解为属于关系 --> 跑车属于汽车,汽车属于交通工具....
[1] 聚集 : has a ,指"有一个"的意思,理解为包含关系--> 人身体包含心脏,大脑,肢体.....
[2] 继承的耦合度相对于聚集要高一些
[3] 由于在继承中通常父类的改变通常会对底层子类的改变带来一定的困难,所以实现代码复用的情况下,应该选择聚集。
[4] 如果编码中需要实现“向上抽取”的操作,则应该考虑使用继承来实现。
小结 :
1. 理解 继承与 聚集的关系 , 理解 聚集 与 聚合 与组合的关系
二十五. 面向对象(子父类中变量的特点)
1 ) . this 与 super 的区别:
1.1 this 代表的是 本类对象的引用
1.2 super 代表的是 父类对象的引用
2 ) . 类的组成 : 变量 , 函数, 构造函数
3 ) . Demo
/*字父类出现后,类成员的特点:
类中成员 :1.变量2.函数3.构造函数
1.变量
若子类中出现非私有的同名成员变量时,子类中要访问本类中的变量,用this;子类中要访问父类中的同名变量,用super
2.函数
3.构造函数*/class Zi extends Fu{int num =4;void show(){System.out.println(super.num);}}class Fu{int num = 5;}class extendsDemo2{public static void main(String[] args){Zi zi=new Zi();Fu fu=new Fu();System.out.println(zi.num+"..."+fu.num);zi.show();System.out.println("Hello world");}}
小结 :
1.牢记 this 与 super的关系
二十六. 面向对象(子父类中函数的特点-覆盖)
1 ) . 覆盖也叫重写,在继承的过程中,当方法出现功能相同,内容不同时,使用重写的方式,有利于扩展
2 ) . 重写和重载的区别 :
2.1 重写 --> 子父类功能相同,内容不同
2.2 重载 -->子父类函数名相同,参数列表不同
3 ) . Demo:
/*字父类出现后,类成员的特点:
类中成员 :1.变量2.函数3.构造函数
1.变量若子类中出现非私有的同名成员变量时,子类中要访问本类中的变量,用this;子类中要访问父类中的同名变量,用super
2.函数
当子类继承父类,其中有些方法功能相同但功能的内容不同时使用覆盖的方式,也就是重写覆盖的特点 :1.子类覆盖父类,必须保证子类的权限大于等于父类权限,才可以覆盖,否则编译失败2.静态只能覆盖静态
牢记 重载与重写的区别:重载:子父类函数名相同,参数列表不同重写:子父类功能相同,内容不同
3.构造函数*/class Zi extends Fu{void show(){System.out.println(zi demo);}}class Fu{void show(){System.out.println(fu demo);}}class extendsDemo2{public static void main(String[] args){Zi zi=new Zi();zi.show();}}
//案例 : 代码复用,关于手机更新class tel{void show(){System.out.println(number);}}class NewTel extends tel{void show(){super.show();System.out.println(name);System.out.println(pic);}}
小结 :
1. 没有条件的调用就是递归,会形成死循环,最终导致内存溢出
二十七
. 面向对象(子父类中构造函数的特点--子类实例化过程)
1 ) . 相关知识点:
1.1 场景:
[1]简述 : 当对子类对象进行初始化时,父类的构造函数也会运行
[2]原因: 子类的构造函数默认第一行有一条隐式的语句super();
[3]解释: super() : 会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();
1.2 问题 :
[1]简述 : 为何子类一定要访问父类中的构造函数?
[2]回答 : 父类中的数据子类可直接获取,当子类对象建立时,需先查看父类对相关数据是如何定义初始化的,因此子类在初始化时需要先看访问下父类的构造函数
[3]ps : 当需要访问父类中指定的构造函数时,通过手动定义super()语句的方式来指定
1.3 结论 :
[1] 父类中有空参构造函数时,子类所有的构造函数,默认都会访问父类中空参数的构造函数,因子类每个构造函数内第一行都有一句 隐式 super();
[2] 父类中无空参构造函数时,子类必须通过super语句形式来指定要访问父类中的构造函数,也可是通过this语句访问本类中的构造函数
[3] 子类中至少有一个构造函数会访问父类中的构造函数
2 ) . Demo :
class Fu{Fu(){System.out.println("Fu demo");}}class Zi extends Fu{Zi(){System.out.println("Zi demo");}}class extendsDemo4{public static void main(String[] args){Zi zi=new Zi();}}
小结 :
1. 在具有继承关系的字父类上,初始化子类时程序必会先初始化父类,因在子类的每一个构造函数中的第一行,都有隐式的默认调用父类构造函数的方法
二十八
.面向对象(final关键字)
1 ) . 核心理论 :
1.1 final可以修饰类,方法,变量
[1] final修饰的类不可以被继承
[2] final修饰的方法不可以被覆盖
[3] final修饰的变量是一个常量,只能被赋值一次
1.2 内部类只能访问被final修饰的局部变量
2 ) . 使用 :
2.1 当某类中的全部方法作为最终方法时,使用final修饰类,该类final修饰不能被继承,因此全部方法不能被重写 --> 俗称的 最终类
2.2 当某类中的某个方法作为最终方法时,使用final修饰该方法,则该方法不能被重写 --> 俗称的最终方法
2.3 当某类中的某个变量作为最终变量时,使用final修饰该变量,则变量变常量,成为固定值 ,既可修饰局部变量,又可修饰成员变量 --> 俗称的 常量
[1] 常量的书写规范 : 所有字母都大写,若由多个单词组成,则单词之间_连接
3 ) . 复习 :
3.1 Public --> 是 访问权限方面的问题 --> 作用多大的范围
3.2 Static --> 是共享数据方面的问题 --> 只关注行为不关注状态时使用
3.3 final --> 是 最终固定方面的问题
二十九. 面向对象(抽象类1,2)
1 ) . 何时使用? 怎么使用?
1.1 当多个类中出现相同功能,但功能主体不同时,可以进行向上抽取,只抽取功能定义,不抽取功能主体,而后用abstract标识的类或方法
2 ) . 抽象类的特点 :
2.1 抽象方法一定在抽象类中
2.2 抽象方法和抽象类都必须被abstract关键字修饰
2.3 抽象类不可以用new创建对象,因为调用抽象方法没意义
2.4 抽象类中的抽象方法若要被使用,则子类必须复写父类中所有抽象方法,而后建立子类对象调用; 若子类只复写父类中的部分抽象方法,则该子类还是一个抽象类
3 ) . Demo :
class Person{abstract void study();}class Student extends Person{void study(){System.out.println("student study");}}class Worker extends Person{void study(){System.out.println("Worker study");}}class AbstractDemo{public static void main(String[] args){//new Person(); //new抽象方法对象无意义}}
4 ) . 抽象类与一般类的区别:
4.1 抽象类用来描述具体的固定事物,而一般类用来实现固定事物 --> 因此 抽象中定义功能但不定义具体方法,而一般类定义功能又定义方法
4.2 抽象类比一般类多了抽象方法 --> 也就是抽象类中可有非抽象方法和抽象方法,而一般类只有非抽象方法
4.3 抽象类不可以被实例化对象,而一般类可以实例化对象
ps : 抽象类中也可不定义方法,这样做的目的仅仅是不让该类实例化对象
小结 :
1. 抽象类中不一定都是抽象方法,但抽象方法一定在抽象类中
三十. 面向对象(抽象类练习)
1 ) . 需求 :
假如我们在开发一个系统时需要对员工进行建模;员工包含三个属性:姓名,工号以及工资;经理除了以上三个属性之外,还包含一个奖金属性;请使用继承的思想设计出员工类和经理类,要求类中必须提供必要的方法进行属性访问;
2 ) . Demo :
//抽取出来的共性员工类public abstract class Employee{private String name;private String id;private double pay;Employee(String name,String id,double pay){this.name=name;this.id=id;this.pay=pay;}public abstract void work();}
//经理类class Manager extends Employee{private int bonus;Manager(String name,String id,double pay,int bonus){super(name,id,pay);this.bonus=bonus;}public void work(){System.out.println("Manger work");}}
//普通员工类class process extends Employee{Manager(String name,String id,double pay){super(name,id,pay);}public void work(){System.out.println("process work");}}
小结 :
1. 在功能确定,但功能内容不确定时使用abstract修饰该方法
三十一
. 面向对象(模板方法模型)
1 ) . 模板方法 : --> 如豆浆机,月饼器,冰块盒子
模板就是做图或设计方案的固定格式
模板方法就是在类中有确定方法和不确定方法的固定格式
2 ) . Demo :
/*需求 : 获取一段程序运行的时间
原理 : 获取程序开始和结束的时间并相减即可
获取时间方法 : System.currenTimeMillis();
模板方法设计模式 : 指在定义功能时,功能的一部分确定,一部分不确定,确定的部分在使用不确定的部分,则将不确定的部分暴漏出去由该类的子类继承完成
ps : 确定的不可改方法用final修饰 , 不确定的可改的方法用abstract修饰*/
abstract class GetTime{public final void getTime(){long start =System.currentTimeMillis();runcode();long end =System.currentTimeMillis();System.out.println("毫秒:"+(end-start));}public abstract void runcode();}
class SubTime extends GetTime{public void runcode(){for(int x=0;x<4000;x++){System.out.println(x);}}}
class AbstractDemo5{public static void main(String[] args){SubTime gt = new SubTime();gt.getTime();}}
三十二 . 面向对象(接口1,2)
1 ) . 简述 :
1.1 格式 : interface {} -->接口中的成员修饰符是固定的
[1] 成员常量修饰格式 : public static final
[2] 成员函数修饰格式 : public abstract
1.2 相关 : 接口的出现将"多继承"通过另一种形式体现出来,即"多实现"
1.3 目的 : 用过来做功能扩展的
2 ) . 复习整合 :
2.1修饰符
[1] class 用于定义类
[2] interface 用于定义接口
[3] abstract 用于定义抽象类
2.2 关系 :
[1] 类与类之间是继承关系
[2] 类与接口之间是实现关系
[3]接口与接口之间是实现关系
[4] 街口与接口之间可以实现多继承
3 ) . 单继承与多实现的问题 :
单继承的情况下是在父类中有非抽象方法可以直接拿来用 -->指选择
多实现的情况下是在父类中都是抽象方法都需要被重写 -->指覆盖
4 ) . 为何不可以多继承,而可以多实现呢?
因为当出现多继承时,则会出现AB是父类,C是子类,AB父类中出现相同方法,C无法选择,就懵逼了
而多实现,AB是接口,C是实现,AB出现相同方法,C一个方法直接重写两个即可,说白了就是继承只能选择不能覆盖,而实现可是覆盖
5 ). Demo:
interface Inter{public static final int NUM=4;public abstract void show();}interface Inter{public abstract void showA();}class Demo{public void function(){};}class Test extends Demo implements Inter,InterA{public void show(){}}class InterfaceDemo{public static void main(String[] args){Test test=new Test();System.out.println(test.NUM);System.out.println(Test.NUM);System.out.println(Inter.NUM);}//多继承
}interface A{void methodA();}interface B{void methodB();}interface C extends A,B{void methodC();}class D implements C{Public void methodA(){}Public void methodB(){}Public void methodC(){}}
小结 :1. 接口中全部都是抽象方法,一旦实现则接口中方法全部都需重写,因此接口中的成员都是Public的2. 接口不可以被实例化对象,只有当接口被子类实现,子类将接口中方法全部覆盖后,则子类可被实例化,否则子类也是抽象类
3 .java支持多实现是对多继承另一种形式的体现
三十三. 面向对象(接口的特点)
1 ) . 主要特点 :
1.1 接口是对外暴露的规则
1.2 接口是程序的功能扩展
1.3 接口可以用来多实现
1.4 类与 接口之间是实现关系,而且类可以继承一个类的同时实现多个接口
1.5 接口与接口之间可以有多继承的关系
2 ) . 生活中关于接口的例子 :
2.1 无线鼠标,无线键盘,无线耳机 -->USB接口
小结 :
1. 实现了分离,促使分工更加明确,降低了耦合性,符合高内聚低耦合的原则2. 耦合性 : 指紧密联系程度 ,也指依赖程度
三十四. 面向对象(接口举例实现)
1 ) . 实现与继承的区别 :
1.1 实现是 like a ,你像我中的一个
1.2 继承是 is a , 你是我中的一个
2 ) . 基本功能与扩展功能 : -->两者都因具体场景具体分析
2.1 基本功能定义在类中
2.2 扩展功能定义在接口中
3 ) . Demo
abstract class Student{abstract void study();void sleep(){System.out.println(sleep);}}
interface Smoking{void smoke();}class ZhangSan extends Student implements Smoking{void study(){}public void smoke(){}}class LiSi extends Student{void study(){}}class InterfaceDemo1{public static void main(String[] args){System.out.println("Hello world!");}}
小结 :
1. 基本功能用继承,拓展功能用实现
三十五
. 面向对象(多态--概念)
1 ) . 简述 :
1.1 定义 : 某一类事物存在的多种体现形态
1.2 案例 : 动物中的猫,狗 ;
[1] 猫是猫,狗是狗; 猫狗同时都是动物 ; 而动物不一定都是猫狗
2 ) . 理解 :
2.1 在对象上的体现 : 过去某一实体对应固定类型,多态的出现让某一实体对应多种类型
2.2 在函数上的体现 : 重载和重写就是多态的体现
3 ) . 重点 :
3.1 多态的体现 : -->
[1] 父类的引用指向了自己的子类对象 ; 例子: Animal x =new Cat(); --> 在实例化对象方面
[2] 父类的引用也可以接受自己的子类对象 ; 例子 : function (Animal a){} --> 在函数传值方面
3.2 多态的前提:
[1] 类与类之间存在关系 : 要么继承,要么实现
[2] 子类与父类之间存在覆盖
3.3 多态的好处 : --> 大大提高程序的扩展性
3.4 多态的弊端 : --> 虽提高了扩展性,但是只能使用父类的引用访问父类中的成员
3.4 多态的应用 : -->见后第三十八章节
3.5 多态的出现代码中的特点(多态使用的注意事项) : -->见后第三十八章节
4 ) . Demo1 :
abstract class Animal{abstract void eat();}class Cat extends Animal{public void eat(){System.out.println("吃猫粮");}public void sleep(){System.out.println("晒太阳");}}class Dog extends Animal{public void eat(){System.out.println("吃狗粮");}public void lookHome(){System.out.println("看家");}}class Pig extends Animal{public void eat(){System.out.println("吃猪食料");}public void fight(){System.out.println("打架");}}
-----------------------------------------------------------------
class InterfaceDemo1{public static void main(String[] args){//方式一:传统的方式/*function(new Cat());function(new Dog());function(new Pig());*///方式二:多态的方式function(new Dog());function(new Dog());function(new Pig());}//方式一/*public static void function(Cat c){c.eat();}public static void function(Dog d){d.eat();}public static void function(Pig p){p.eat();}*///方式二public static void function(Animal A){A.eat();}}
三十六
. 面向对象(多态-扩展性) -->见上一章节笔记
三十七. 面向对象(多态--转型)
1 ) . 关于转型 : -->存在关系才能转型
1.1 若多个子类(猫类)都需使用父类(动物类)中的基本功能 : --> 类型提升 :向上转型 --> 指采用多态的继承
1.2 若多个子类(猫类)都需使用子类(猫类)的特有功能 : --> 类型转化 : 向下转型 -->指采用多态的强制
2 ) . Demo :
abstract class Animal{abstract void eat();}class Cat extends Animal{public void eat(){System.out.println("吃猫粮");}public void sleep(){System.out.println("晒太阳");}}class Dog extends Animal{public void eat(){System.out.println("吃狗粮");}public void lookHome(){System.out.println("看家");}}class Pig extends Animal{public void eat(){System.out.println("吃猪食料");}public void fight(){System.out.println("打架");}}class InterfaceDemo2{/*public static void main(String[] args){//1.子类使用父类的通用方法//方式一:传统的方式function(new Cat());function(new Dog());function(new Pig());//方式二:多态的方式function(new Dog());function(new Dog());function(new Pig());}//方式一/*public static void function(Cat c){c.eat();}public static void function(Dog d){d.eat();}public static void function(Pig p){p.eat();}*///方式二/*public static void function(Animal A){A.eat();}*/public static void main(String[] args){//2.子类使用自身的特有方法//方式一:/*Animal c =new Cat();Cat c1 = (Cat)c;c1.sleep();*///方式二:封装function(new Cat());function(new Dog());function(new Pig());}//一般情况下是某一事物的多种形态是固定个数的,采用if else的方式去判断public static void function(Animal A){A.eat();if(A instanceof Cat){Cat A1=(Cat)A;A1.sleep();}else if(A instanceof Dog){Dog D1=(Dog)A;D1.lookHome();}else if(A instanceof Pig){Pig P1=(Pig)A;P1.fight();}else{System.out.println("哈哈");}}}
小结 :
1. 我们能转换的是父类引用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换2. 多态自始至终都是子类对象在做着变化
三十八. 面向对象(多态--示例)
1 ) .多态的应用 :
/*基础班学生:学习,睡觉高级班学生:学习,睡觉可以将这两类事物进行抽取*/
//向上抽取的共性类abstract class Student{public abstract void study();public void sleep(){System.out.println("躺着睡");}}
//调用使用的工具类class DoStudent{public void doSome(Student stu){stu.study();stu.sleep();}}
class BaseStudent extends Student{public void study(){System.out.println("base study");}public void sleep(){System.out.println("坐着睡");}}
class AdvStudent extends Student{public void study(){System.out.println("Adv study");}public void sleep(){System.out.println("坐着睡");}}
//测试类class InterfaceDemo3{public static void main(String[] args){DoStudent ds=new DoStudent();ds.doSome(new BaseStudent());ds.doSome(new AdvStudent());}}
2 ) . 多态的出现代码中的特点(多态使用的注意事项)
小结 :
1. 通过多态封装工具类
三十九
. 面向对象(多态中成员的特点)
1 ) . 在具有继承关系的类中静态与非静态的区别 :
1.1 静态没有重写重载 , 而非静态有重写重载
1.1 静态在内存中采用的是静态绑定,而非静态在内存中采用的是动态绑定
1.3 静态参考引用类型变量所属;非静态参考实例化对象的类
2 ) . 在多态中成员函数(非静态函数)的特点 :
2.1 在编译时期: 参考引用类型变量所属类中是否有调用的方法,若有:则编译通过;若没有,则编译失败
2.2 在运行时期: 参考实例化对象所属的类中是否有调用的方法
通过外在代码体现简记 : 成员函数在多态调用时,编译看左边(引用类型变量所属的类),运行看右边
3 ) . Demo1 :
/**///在静态情况下/*class Fu{static int num = 8;public static void Sleep(){System.out.println("Fu sleep");}}class Zi extends Fu{static int num = 5;public static void Sleep(){System.out.println("Zi sleep");}} *///在非静态情况下class Fu{int num = 8;public void Sleep(){System.out.println("Fu sleep");}}class Zi extends Fu{int num = 5;public void Sleep(){System.out.println("Zi sleep");}}class InterfaceDemo4{public static void main(String[] args){//在静态情况下//子类覆盖父类的方法,调用的是子类方法// Zi zi = new Zi();// zi.Sleep();//子类覆盖父类的方法,调用的是父类方法// Fu zi1 =new Zi();// zi1.Sleep();//调用的是子类中的num// Zi zi2 =new Zi();// System.out.println(zi2.num);//调用的是父类中的num// Fu zi3 =new Zi();// System.out.println(zi3.num);System.out.println("------------------------");//小结 : 在继承关系中的静态情况下,子类中有属性,便用子类的;子类中没有属性,便用父类中的//在非晶态的情况下//子类覆盖父类的方法,调用的是子类方法Zi zi4 = new Zi();zi4.Sleep();//子类覆盖父类的方法,调用的是子类方法Fu zi5 = new Zi();zi5.Sleep();//调用的是子类中的numZi zi6 =new Zi();System.out.println(zi6.num);//调用的是父类中的numFu zi7 =new Zi();System.out.println(zi7.num);//小结: 在继承关系中的非静态情况下,子类中有属性,便用子类的;子类中没有属性,便用父类中的 ; 但静态/非晶态的变量除外}}
小结 :
1. 在继承关系/多态关系下,对于非静态函数或非静态变量 子类只要自己有则使用自己的,子类没有则使用父类的;而 静态变量/静态函数 则会使用直接选择父类的2. 静态变量/函数就是模板就是不可动资产,只能使用父类,是固定的
四十
. 面向对象(多态的主版示例)
1 ) . 理解 :
1.1 从宏观整体布局到--> 类型分类结构-->微观实现
1.2 PCI P =new NetCard() -- > PCI可是说是 NetCard 的 类型 , NetCard 是类型中的一种,也就是 PCI的多种形态的一种是 NetCard
2 ) . Demo :
/*需求 : 电脑运行实例分析 : 电脑运行基于主板*/class MainBoard{public void run(){System.out.println("MainBorard run....");}public void userPCI(PCI P) //PCI P =new NetCard() 接口类型引用指向自己的子类对象{if(P!=null){P.open();P.close();}}}interface PCI{void open();void close();}class NetCard implements PCI{public void open(){System.out.println("NetCard open....");}public void close(){System.out.println("NetCard close....");}}class SoundCard implements PCI{public void open(){System.out.println("SoundCard open....");}public void close(){System.out.println("SoundCard close....");}}class DoTextDemo{public static void main(String[] args){MainBoard m = new MainBoard();m.run();m.userPCI(null);m.userPCI(new NetCard());m.userPCI(new SoundCard());}}
小结 :
1. 接口降低了耦合性,提高了功能扩展性,提供了规则
四十一. 面向对象(多态的扩展示例)
1 ) . 理解 :
1.1 中转站-->转接器 -->将一堆东西归类别,将类别存入中转站,调用时在中转站找到相关类型,再找到相关东西,也就是第三方拓展-->用接口和多态实现
2 ) . Demo --> 以下是伪代码 ,只仅供参考思想
/*需求:数据库的操作1.连接数据库 : JDBC , hibernate2.操作数据库 : CRUD --> Create,update,update,delete3.关闭数据库连接*/interface UserInfoDao{void add();void delete();}class UserInfoByJDBC implements UserInfoDao{public void add(User user){1.JDBC连接数据库2.使用sql添加语句添加数据3.关闭连接}public void delete(User user){1.JDBC连接数据库2.使用sql删除语句删除数据3.关闭连接}}class UserInfoByHibernate implements UserInfoDao{public void add(User user){1.Hibernate连接数据库2.使用sql添加语句添加数据3.关闭连接}public void delete(User user){1.Hibernate连接数据库2.使用sql删除语句删除数据3.关闭连接}}class DoTextDemo1{public static void main(String[] args){UserInfoDao u = new UserInfoByHibernate();u.add(user);u.delete(user);}}
小结 :
1. 多态用来类型管理; 接口用啦共性方法复用;
四十二. 面向对象(Object类,equals())
1 ) . 理解 :
1.1 == --> 比较的是数值是否相等
1.2 equals --> 比较的是引用地址
1.3 instanceof --> 比较的是 引用数据类型
2 ) . Object -->
定义 : 使所有对象的直接或间接父类,传说中的上帝
特性 : 该类中定义的是所有对象都具备的 功能
3 ) . Demo :
class Demo{private int num;Demo(int num){this.num=num;}public boolean equals(Object obj){if(!(obj instanceof Demo))return false;Demo d=(Demo)obj;return this.num==d.num;}}class Person{}class ObjectDemo{public static void main(String[] args){Demo d1=new Demo(4);Demo d2=new Demo(4);Person p=new Person();System.out.println(d1.equals(d2));System.out.println(d1.equals(p));}}小结 :
1. 明白类型与类型的比较,可沿用Object作为对象去复用
四十三. 面向对象(Object类的toString())
1 ) . Demo:
class Demo{}class ObjectDemo{public static void main(String[] args){Demo d1=new Demo();//以下两句都是返回对象的字符串表示,第一个完整版,第二个是封装版
System.out.println(d1.getClass().getName()+"@"+Integer.toHexString(d1.hashCode()));
System.out.println(d1.toString());}}
1.1 d1.getClass().getName() -->获取实例化对象的类名
1.2 d1.hashCode()) --> 获取实例化对象的哈希码值
1.3 Integer.toHexString( ) --> 将interger类型的数值换算成十六进制表示
1.4 Integer.toHexString(d1.hashCode())) --> 将实例化对象的哈希码值以十六进制的方式表示
小结 :
1. 所有的对象都是用class 描述的,class 是类文件对象
2.所谓的反编译就是通过class对象中的getMethods反向获取任意代码的方法,通过class文件
四十四
. 面向对象(内部类访问规则)
1 ) . 简述 :
1.1 概念 : 将一个类定义在另一个类的里面,对里面那个类就成为内部类(内置类/嵌套类)
1.2 访问特点 :
[1] 内访外 : 内 部类可以直接访问外部类中的成员,包括私有成员
[2] 外 访内 : 而外部类要访问内部类中的成员必须建立内部类的对象
2 ) . 内部类为何可以访问外部类中的成员 :
[1] 是因为内部类中持有了一个外部类的引用,格式 : 外部类名.this
3 ) . Demo :
class Outer{private int num=3;void show(){//外部类访问内部类变量方式 --> 创立对象访问Inter inter = new Inter();inter.show();System.out.println("NUM:"+num);}class Inter{private int num=2;//内部类访问外部类变量方式 --> 直接调取void show(){int num=1;//第一个是1,先访问局部变量System.out.println("NUM:"+num);//第二个是1,其次访问本类变量System.out.println("NUM:"+this.num);//第三个是1,而后访问外部类变量System.out.println("NUM:"+Outer.this.num);}}}class ObjectDemo1{public static void main(String[] args){Outer outer=new Outer();outer.show();}}
小结 :
1. 内部类访问外部类直接调取,外部类访问内部类需创建对象
2. 类可以私有化,在具有内部类与外部类的关系时,内部类是可以私有化的,因为此时内部类是外部类的成员变量
四十五. 面向对象(静态内部类)
1 ) . 复习 : -->访问格式
1.1 外访内 : 当内部类定义在外部类的成员位置上,而非私有时,可在外部其他类中直接建立内部类对象
[1] 访问格式 : 外部类名.内部类名 变量名=new 外部类对象.内部类对象(); --> Outer.Inter in = new Outer().new Inter();
1.2 内访外 : -->可直接访问调用
1.3 当内部类在外部类的成员位置上时,可被成员修饰符所修饰 :
[1] private : -->将内部类在外部类中进行封装
[2] static : --> 将内部类进行共享特性, 但 当内部类用static 修饰之后, 则只能访问外部类中的static成员,出现了访问权限
1.4 在外部其它类中 ,如何直接访问static内部类非静态成员呢?
2 ) . Demo:
class Outer{private static int num=3;static class Inner{static void show(){System.out.println("inner1:"+num);}}static class Inner1{static void show(){System.out.println("inner2:"+num);}}static class Inner2{static void show(){Inner1.show();System.out.println("inner3:"+num);}}}class ObjectDemo2{public static void main(String[] args){//在非静态时/* Outer.Inner inner=new Outer().new Inner();inner.show(); *///在外部其他类中,如何直接访问static内部类的非静态成员?// new Outer.Inner().show();//在外部其他类中,如何直接访问static内部类的静态成员?Outer.Inner2.show();}}
小结 :
1. 当内部类中定义了静态成员,则该内部类必须是静态的2. 当外部类中的静态方法访问内部类时,内部类也必须是静态的
四十六. 面向对象(内部类定义原则)
1 ) . 内部类何时用 : -->用于程序设计
1.1 当描述事物时,事物的内部还有事物,该事物用内部类来描述,因为内部类可访问外部类的内容
2 ) . Demo :
class Body{private class heart{void start(){......};void stop();}private class head{void start();void stop();}public void show(){new heart().start();new head().start();}}
小结 :
1. 使用内部类时注意封装内部类,而后提供一个方法(访问方式)
四十七. 面向对象(匿名内部类)
1 ) . 复习 : 内部类定义在局部时 :
1.1 不可以被成员修饰符修饰
1.2 可以直接访问外部类中的成员,因为持有外部类中的引用,若访问局部变量则需要用final修饰
2 ) . Demo1:
class Outer{int num=5;void show(){final int num=8;class inner{void function(){System.out.println("局部num:"+num);System.out.println("外部num:"+Outer.this.num);}}new inner().function();}}class ObjectDemo4{public static void main(String args[]){new Outer().show();}}
3 ) . 匿名内部类 :
3.1 匿名内部类其实就是内部类的简写格式
3.2 定义匿名内部类的前提: 内部类必须是继承一个类或实现接口
3.3 匿名内部类的格式 : new 父类或者接口(){定义子类的内容}
3.4 其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖(有内容)
3.5 匿名内部类中定义的方法最好不要超过三个,因为一次只能调用一个
4 ) . Demo2 :
abstract class AbsDemo{abstract void show();}class Outer{int num=5;/* class Inner extends AbsDemo{void show(){System.out.println("num:"+num);}} */public void function(){// new Inner().show();//上边注释掉的内容,以下代码可替代,是简化版的匿名内部类标准写法/* new AbsDemo(){void show(){System.out.println("num:"+num);}}.show(); */AbsDemo d= new AbsDemo(){// int num =8; 这里定义的有局部变量便会调用这个,若没有则会调用类中的成员变量void show(){System.out.println("num:"+num);}void show1(){System.out.println("num1:"+num);}};d.show();d.show1(); //调用第二个失败,匿名内部类中一次只能调用一个}}class ObjectDemo41{public static void main(String args[]){new Outer().function();}}
5 ) . Demo3 -->案例练习 :
interface Inter{void method();}class Test{static class Inner implements Inter{public void method(){System.out.println("method run");}}static Inter Function(){return new Inter(){public void method(){System.out.println("method run");}};}}class InnerClassText{public static void main(String args[]){Test.Function().method(); //-->调用类中的内部类的方法时需要NEWnew Test.Inner().method(); //-->调用类中方法中的匿名内部类时不需要NEW//解析 : Test.Function().method();1.Test.Function() : Test类中有一个静态的方法function2..method() : function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象3.因为只有Inter类型的对象,才可以调用method方法}}
6 ) . Demo4 -->面试案例 : -->下面的代码是否可运行
new Object(){void show(){System.out.println("show run");}}.show();
6.1可运行,因为是通过object建立的匿名内部类,而后调用其内部shou方法,误区在于 大多数人没想到Object是java已存在的最大父类
小结 :
1. 静态不可以修饰局部变量或局部类,只能修饰成员变量,或类2. 匿名内部内类=匿名子类对象,匿名对象只能一次调用一次方法
3. 在存在内部类的关系下,调用类中方法需要实例化类,调用方法中匿名类无需实例化类