封装
1、是什么?
1、可以理解为:我在网上买了个快递。我要退款。退款我就要包装(也就是封装)。
2、干嘛的?
1、我们用封装的思想,来把我们写的一个方法封装起来,可以让其他模块业务调用。
2、这样我们就可以不用重复写一个东西了,只要类引用一下就好了。
1、主要步骤方法
1、我们定义私有属性或方法。
2、我们要提供公共的方法,方便其他模块或程序调用
3、怎么玩
1、实例
1、我们定义一个类Class :People
2、定义get、set方法
3、代码如下
package org.example.fengzhuang;
public class People {
private String name;
private int age;
//get/set方法
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;
}
}
4、调用
public class Main {
public static void main(String[] args) {
People p = new People();
p.setName("张三");
p.setAge(20);
System.out.println(" name= " +p.getName() );
}
}
继承
是什么?
1、生活中的实例,父亲去世了,儿子继承父亲的财产。儿子也可以有自己的财产。
干嘛用?
1、避免代码的臃肿,代码量大的问题。
怎么玩?
1、实例
1、这里我们准备两个类,一个是Father、1个是son的类
2、我们编写一个父类的show方法,儿子不写。代码如下
//父类
package org.example.fengzhuang;
public class Father {
public Father(){
//子类必须调用父类的构造器,完成父类初始化,所以父类要有个构造器
System.out.println("父类构造方法");
}
public void show(){
System.out.println("父类show方法");
}
}
//子类
package org.example.fengzhuang;
public class Son extends Father{
public static void main(String[] args) {
Son son = new Son();
// 我是儿子:我要调用我爹的方法
son.show();
}
}
注意(细节)
1、子类继承了所有父类的属性和方法,私有属性和方法子类不能直接访问,要通过父类提供公共方法去访问(这句话意思是:老爹也可能藏私房钱,要经过父亲的告诉,询问才能知道)
2、子类必须调用父类的构造器,完成父类初始化
3、如果父类没有提供无参构造器,则子类必须使用super去指定父类使用的哪个构造器完成对父类工作的初始化(父类有多个构造器,子类必须用super指向一个构造器)
4、super必须放在构造器中第一行,且只能在构造器使用。
5、super和this 死对头,不能同时调用父类和子类的构造器
6、Object是顶级类,所有子类的父类
7、父类构造器的调用不限直接父类、间接父类也是
(1)C继承B,B继承A,C间接继承A类
8、子类最多只能继承一个父类,只能有一个直接父类
9、不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
继承的原理和内存图
1、super使用细节
1、先找自己的、找不到再依照层级往上找
2、this.ff() =ff()
3、super.ff():通过自身找父类
2、方法覆盖
1、子、父类的参数和方法名从要完全一致
2、父类方法访问权限>=子类
3、继承内存分布图

多态
是什么?
1、多态是同一个行为具有多个不同表现形式或形态的能力。
2、多态就是同一个接口,使用不同的实例而执行不同操作
前提?
1、两个对象存在继承关系
1、一个对象的编译类型和运行类型可以不一致
(1)Animal anim = new Dog():编译类型是Animal,运行类型是Dog
2、编译类型在定义对象时,就确定了,不能改变
3、运行类型是可以改变的
(1)anim = new Cat();
4、编译类型看定义时 = 号的左边,运行类型看 =号的右边
5、向上转型本质:父类的引用指向了子类对象
6、可以调用父类的所有功能,不能调用子类的特有方法(儿子私藏,父亲不知道)实际上是因为:编译类型不同!
7、最终是java运行不是编译器(javac),运行效果看子类的具体实现(调用的方法)
怎么玩?
1、多态的向上转型规则
1、可以调用父类中的所有成员(访问权限)
2、不能调用子类特有方法
(1)eg:
3、编译阶段,调用哪些成员,是编译类型决定的
4、最终是java运行不是编译器(javac),运行效果看子类的具体实现(调用的方法)
2、多态的向下转型规则
1、目的:为了解决不能调用子类中特有的方法(父亲用强转的棍子打儿子,就能得到儿子的私藏)
2、语法:子类类型 引用名 = (子类类型) 父类引用(父类的对象); //向下转型需要先向上转型
3、只能强转父类的引用,不能强转父类的对象
4、要求父类的引用必须指向当前目标类型的对象
5、可以调用子类类型中的所有成员。(父类的也行)
3、实操
//Test2
public class Test2 {
public static void main(String[] args) {
// 向上转型
Father father = new Son();
father.work1(father);
// father.work();//调用不了儿子方法
// 向下转型
Son son = (Son)father;
son.work();
// instanceof 使用
Father father1 = new Girl();
father1.work1(father1);
}
}
//Father
public class Father {
// public Father(){
// System.out.println("父类构造方法");
// }
// public void show(){
// System.out.println("父类show方法");
// }
public void work1(Object o){
if(o instanceof Son){
System.out.println("(父类中的方法)我要去搬东西");
} else if (o instanceof Girl) {
System.out.println("我要去洗碗了");
}
}
}
//Son
public class Son extends Father{
public void work(){
System.out.println("(儿子自己的方法)我去搬东西了");
}
}
4、多态的注意事项
1、属性没有重写只说!属性的值看编译类型
2、instanceof 比较操作符,用于判断对象的类型是否为xx类型或xx的子类型【返回Boolean值】
5、java的动态绑定机制(‼)
1、当调用对象方法时候,该方法会和该对象的内存地址/运行类型绑定
2、当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
6、关键字
1、判断xxx是不是运行的子类或父类
eg:if(person[i] instanceof student)//判断person【i】的运行类型是不是student
7、总结
1、Object类详解
equals方法:比较
2、equals和== 的对比
(1)==:表示基本判断类型、引用判断类型
(2)==:基本判断类型:值是否相等
(3)==:引用判断类型:地址是否相等
(4)equals:只能判断引用类型
2、hashCode方法()
1)提高具有哈希结构的容器的效率!
(2)两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
(3)两个引用,如果指向的不同对象,则哈希值是不一样的
(4)哈希值主要根据地址来!,不能完全等价于地址
3、toString()方法
(1)原理:返回全类名(包名+类名)+对象hashCode值转成16进制的字符串。
(2)作用:子类往往重写toString方法,用于返回对象的属性信息
(3)重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式。
(4)当直接输出一个对象时,toString方法会被默认的调用
eg:System.out.println(monster)==monster.toString()