覆写:就是子类和父类有个一样(方法名,参数列表,返回值都一样)的成员方法覆写指定成员方法,只有成员方法可以覆写
应用场景
1,如果父类方法不能满足子类需求的时候,需要对方法进行覆写。
覆写条件
1必须是有继承关系
2方法名,参数列表,返回值必须相同
3不能有更宽泛的异常
继承最基本的作用:代码重用
继承最重要的功能:方法覆写
覆写目的:
1满足当前需求
2错误越来越少
3使用范围越来越广
4功能越来越强
覆写 就是 子类和父类有个一样(方法名,参数列表,返回值都一样)的成员方法
* 覆写特指成员方法,只有成员方法可以覆写
*
* 什么时候需要覆写 :
* 如果父类方法不能满足子类需求的时候,需要对方法进行覆写
*
* 覆写条件
* 1 必须是有继承关系
* 2 方法名,参数列表,返回值 必须相同
* 3 不能拥有更低访问权限
* 4 不能有更宽泛的异常
*
* 继承最基本的作用 : 代码重用
* 继承最重要的功能 : 方法覆写
*
* 覆写目的 :
* 1 满足当前需求
* 2 错误越来越少
* 3 使用范围越来越广
* 4 功能越来越强
*
* overload 和 override的区别
*/
public class Override_01 {
public static void main(String[] args) {
Cat cat = new Cat();
cat.move();
Dog dog = new Dog();
dog.move();
}
}
class Animal{
public void move(){
System.out.println("动物在移动");
}
}
class Cat extends Animal {
// 不能满足子类需求,进行重写
public void move() {
System.out.println("猫在走猫步");
}
}
class Dog extends Animal {
// 不能满足子类需求,进行重写
public void move() {
System.out.println("狗在爬");
}
}
Final
是什么:final是修饰符,表示最终的,不能更改的
能干什么:final修饰的类不能被继承
修饰的成员方法不能被覆写
修饰的变量没有默认值,必须显示赋值,并且整个生命周期中值不可更改
常量一般写为:public static final,常量命名 建议全部大写
public class Final_01 {
public static void main(String[] args) {
final int i = 2;
// i = 3;
}
}
// final类不能被继承
//final class A{
class A{
// final方法不能被覆写
// public final void m1(){
public void m1(){
}
}
class B extends A{
public void m1(){
}
}
package _10_final;
public class Final_02 {
public static void main(String[] args) {
// final修饰的引用类型,user变量的值不能更改
final User user = new User(22);
// 和user引用指向的堆内存空间中的数据没有关系
// 因为age又没有加final修饰
user.age = 24;
user.age = 55;
// 引用user使用final修饰,所以不能更改user变量的值
// user = null;
System.out.println(user.age);
}
}
class User {
int age;
public User(int age) {
super();
this.age = age;
}
}
多态
软件设计六大原则
单一职责原则
里氏替换原则 : 能使用父类的地方就一定可以使用子类
依赖倒置原则
接口隔离原则
迪米特原则
开闭原则
是什么
多态就是父类引用指向子类对象
父类引用:使用父类类型创建的引用类型变量
指向:通向这个引用类型变量,可以找到那个对象
子类对象:创建的子类对象
public static void main(String[] args){
A a=new A();
m1(a);
}
public static void m1(XX xx){
xx.m1();
}
class XX{
public void m1(){
}
}
1
package Test.test3;
public class Duotai {
public static void main(String[] args){
An a=new An();
System.out.println(a.age);
System.out.println(a.name);
a.eat();
a.m1();
}
}
class An{
int age=19;
static String name="dong";
public void eat(){
System.out.println("eat");
}
public static void m1(){
System.out.println("eat");
}
}
class Cat extends An{
int age=1;
static String name="not";
public void eat(){
System.out.println("eat fish");
}
public static void m1(){
System.out.println("21eat");
}
public void move(){
System.out.println("zoulu");
}
}
class Dog extends An{
public void move(){
System.out.println("claw");
}
}
2
public class Duotai2 {
public static void main(String[] args) {
Sup s1 = new Sup();
Sub sub = new Sub();
m1(sub);
Sup sup = m2();
}
public static void m1(Sup s) {
}
public static Sup m2() {
return new Sub();
}
}
class Sup {
}
class Sub extends Sup {
}
3
public class Duotai3 {
public static void main(String[] args) {
An a=new Cat();
System.out.println(a.age);
a=new Dog();
move(a);
}
public static void move(An a){
if(a instanceof Cat){
Cat c=(Cat) a;
c.move();
}else if(a instanceof Dog){
Dog d=(Dog) a;
d.move();
}
}
}
4
public class Duotai4 {
public static void main(String[] args) {
Sub1 sub = new Sub1();
sub.m1();
System.out.println("sub:"+sub);
}
}
class Sup1 {
int i = 12;
static int age = 3;
public void m1() {
System.out.println(i);
System.out.println(age);
m2();
}
public void m2() {
System.out.println(i);
System.out.println("fuleideM2");
}
}
class Sub1 extends Sup1 {
int i = 45;
static int age = 32;
public void m2() {
System.out.println(i);
System.out.println(super.i);
System.out.println("zileideM2");
}
}
5
public class Duotai5 {
public static void main(String[] args) {
A a = new A();
m1(a);
B b = new B();
m1(b);
}
public static void m1(A a) {
a.m1();
}
public static void m1(B a) {
a.m1();
}
}
class A {
public void m1() {
System.out.println(213);
}
}
class B {
public void m1() {
System.out.println(234);
}
}
instanceof:判断某个对象是否由某个类实例化而来。
隐秘多态
public class YinDuotai {
int i = 14;
public void m1() {
System.out.println(this + ".......");
/**
* this发生多态 this是成员变量,保存当前类对象的内存地址,并且谁调用的该方法,this就是谁
* this用来保存当前对象的内存地址,那么this一定有数据类型 1当前类类型 2父类类型(多态)
* 因为this可以调用当前类中的所有属性,所以一定不是父类类型,因为多态会丢失子类特有的属性所以this一定是当前类类型
* (this所在的类,就是当前类)而 this出现在 Sup1中, 所以就等于 Sup1 this;
* 准调用该方法,this就是进,但是因为继承关系,是通过子类对象调用的m1方法,所以this指向子类对象 Sup1 this = new
* Sub1(); 总结∶通过子类对象调用父类的方法的时候,父类这个方法的上下文环境就是多态环境
*/
}
}
Object
Object是java提供的根类,所有类都要直接或者间接继承Object
意味着 Object中的方法,是所有类都有的
Object在java.lang.Object 所以 使用不需要导包
getClass : 获取运行时类,反射机制讲解
Clone : 克隆对象,废弃
Notify,notifyAll,wait : 让线程进入等待,和唤醒线程,多线程讲解
toString,finalize,equals,hashCode(散列表讲解)
Equals
/**
* Equals : 设计目的 是比较两个对象是否相等
* 基本类型比较值,引用类型比较地址,
* 我们比较引用类型的时候不会比较地址,因为不同对象的地址一定是不同的
* 除非你就想比较地址(没有任何价值)
*
* 两个对象进行比较的时候,肯定是用有价值的属性进行比较,所以不会使用 == ,而是使用equals
*
* 而 默认的Object中的equals方法,比较内存地址
* public boolean equals (Object obj){ return this == obj; }
* 因为默认不知道比较什么属性,所以默认比较内存地址,根据自己的需求 进行方法重写即可
*
* 不同类没有可比性
* 并且 任何引用类型比较都需要转换为基本类型比较
* @author moon
*
*/
public class Equals {
public static void main(String[] args) {
Student s1=new Student(1,"zhang");
Student s2=new Student(1,"zhang");
System.out.println(s1.equals(s2));
}
}
class Student{
int id;
String name;
public Student(int id,String name){
super();
this.id=id;
this.name=name;
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj instanceof Student){
Student s1=(Student)obj;
if(this.id==s1.id&&this.name.equals(s1.name)){
return true;
}
}
return false;
}
}
Finalize
/*** JVM四大特性 :
* 跨平台,面向对象,多线程,自动垃圾回收机制
*
* 当没有更多引用指向该对象的时候,此时该对象被视为垃圾数据
*
* Object中的finalize方法,是当对象被回收之前,自动调用该方法
* 1 finalize方法所有对象都有
* 2 finalize方法不需要程序员调用,由系统自动调用
* 3 就算程序员对finalize方法进行调用,也只是单纯的方法调用而已,并没有垃圾回收功能
* 4 因为finalize方法并不会垃圾回收,而且被回收之前,自动执行一次而已
* 5 结合finalize方法的执行特征,可以在对象销毁之前,做一些关闭资源等销毁操作
* @author moon
*/
public class Finalize {
public static void main(String[] args) {
Finalize f=new Finalize();
f=null;
//垃圾多了,自动回收
// for(int i=0;i<999999;i++){
// new Finalize();
// }
System.gc();
}
@Override
protected void finalize(){
System.out.println(this+"over");
}
}
HashCode
/*** hashCode : 设计目的 ,是为了给每个对象生成一个唯一的标识符
* 同一个对象,生成多次,一定是相同的值,但是不同的对象生成多次,也有可能生成相同的值,哈希冲突
*
* hashCode方法是根据hash算法得到的哈希值
*
* hash算法 : 是一种安全的加密算法,把不定长的值,转换为定长的值,并不能保证其唯一性
*
* 算法 :
* 直接寻址法 , 数字分析法,平方取中法,折叠法,随机数法,除留余数法
* @author moon
*/
public class HashCode {
@Override
public int hashCode() {
return 18;
}
public static void main(String[] args) {
HashCode h=new HashCode();
HashCode h1=new HashCode();
System.out.println(h);
System.out.println(h1);
System.out.println(h.hashCode());
System.out.println(Integer.toHexString(h.hashCode()));
}
}
toString
- toString设计目的 : 返回该对象的字符串形式
- Object中的toString方法 默认返回内存地址
- 当我们输出一个 引用类型对象的时候 会自动调用该对象的toString方法
-
}public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode());
/**
* toString设计目的 : 返回该对象的字符串形式
*
* Object中的toString方法 默认返回内存地址
*
* 当我们输出一个 引用类型对象的时候 会自动调用该对象的toString方法
* public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
* @author moon
*
*/
public class ToString {
public static void main(String[] args) {
User u=new User(12,"zang");
System.out.println(u);
}
}
class User{
int age;
String name;
public User(int age, String name){
super();
this.age=age;
this.name=name;
}
@Override
public String toString(){
return "年龄:"+age+",姓名:"+name;
}
}