super关键字
-
基本介绍
super代表父类的引用,用于访问父类的属性,方法,构造器
-
基本语法
- 访问父类的属性,但不能访问父类的private属性 super.属性名;
- 访问父类的方法,不能访问父类的private方法super.方法名(参数列表);
- 访问父类的构造器:super(参数列表);只能放在构造器的第一句,只能出现一句
/** *super的使用 */ public class B extends A { public int n1 = 888; public void test() { System.out.println("super.n1=" + super.n1); super.cal(); } public void hi() { System.out.println(super.n1 + " " + super.n2 + " " + super.n3 ); } public void cal() { System.out.println("B 类的 cal() 方法..."); } public void sum() { System.out.println("B 类的 sum()"); this.cal(); System.out.println(n1); System.out.println(this.n1); System.out.println(super.n1); } public void ok() { super.test100(); super.test200(); super.test300(); } public B() { super("jack"); } }
-
super的便利处
- 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)
- 2.当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super.如果没有重名,使用super、this、直接访问是一样的效果。
- super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则。A->B->C,当然也需要遵守访问权限的相关规则
object类
-
equals方法
==和equeals对比
- ==既可以判断基本类型又可以判断引用类型
- equals只能判断引用类型,子类中往往重写该方法用于判断内容是否相等
-
如何重写equals方法
/** *如何重写equals方法 */ public class EqualsExercise01 { public static void main(String[] args) { Person person1 = new Person("jack", 10, '男'); Person person2 = new Person("jack", 20, '男'); System.out.println(person1.equals(person2));//假 } } class Person{ private String name; private int age; private char gender; public boolean equals(Object obj) { if(this == obj) { return true; } if(obj instanceof Person) { Person p = (Person)obj; return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender; } return false; } public Person(String name, int age, char gender) { this.name = name; this.age = age; this.gender = gender; } 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; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } }
-
hashCode方法
- 返回该对象的哈希值,支持此方法是为了提高哈希表的性能
- 实际上,由object类定义的hashCode方法确实会针对不同的对象返回不同的值
- 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
- 两个引用,如果指向的是不同的对象,则哈希值是不一样的
- 哈希值主要是根据地址号来的,不能完全将哈希值等价于地址
/** *hashCode的使用 */ public class HashCode_ { public static void main(String[] args) { AA aa = new AA(); AA aa2 = new AA(); AA aa3 = aa; System.out.println("aa.hashCode()=" + aa.hashCode()); System.out.println("aa2.hashCode()=" + aa2.hashCode()); System.out.println("aa3.hashCode()=" + aa3.hashCode()); } } class AA {}
-
toString方法
- 基本介绍默认返回:全类名+@+哈希值的十六进制,【查看Object的 toString方法】子类往往重写toString方法,用于返回对象的属性信息
- 重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式.
- 当直接输出一个对象时,toString 方法会被默认的调用,比如System.out.printn(monster): 就会默认调用monster.toString()
/** *toStrig的使用 */ public class ToString_ { public static void main(String[] args) { Monster monster = new Monster("小妖怪", "巡山的", 1000); System.out.println(monster.toString() + " hashcode=" + monster.hashCode()); System.out.println("==当直接输出一个对象时,toString 方法会被默认的调用=="); System.out.println(monster); } } class Monster { private String name; private String job; private double sal; public Monster(String name, String job, double sal) { this.name = name; this.job = job; this.sal = sal; } @Override public String toString() { return "Monster{" + "name='" + name + '\'' + ", job='" + job + '\'' + ", sal=" + sal + '}'; } @Override protected void finalize() throws Throwable { System.out.println("fin.."); } }
-
finalize方法
- 当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
- 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法。
- 垃圾回收机制的调用,是由系统来决定(即有自己的GC算法去),也可以通过System.go()主动触发垃圾回收机制
/** *finalize的使用 */ public class Finalize_ { public static void main(String[] args) { Car bmw = new Car("宝马"); bmw = null; System.gc(); System.out.println("程序退出了...."); } } class Car { private String name; public Car(String name) { this.name = name; } @Override protected void finalize() throws Throwable { System.out.println("我们销毁 汽车" + name ); System.out.println("释放了某些资源..."); } }
类变量
-
定义
类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改时,修改的也是同一个变量
-
定义语法
访问修饰符 static 数据类型 变量名;
-
访问语法
类名.类变量名
对象名.类变量名
/** *类变量的使用 */ public class VisitStatic { public static void main(String[] args) { System.out.println(A.name); A a = new A(); System.out.println("a.name=" + a.name); } } class A { private int num = 10; }
-
类变量注意事项和细节
-
什么时候需要用类变量
当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如:定义学生类,统计所有学生共交多少钱。Student (name,staticfee)
-
类变量与实例变量(普通属性)区别
类变量是该类的所有对象共享的,而实例变量是每个对象独享的。
-
加上static称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量
-
类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,但java设计者推荐我们使用 类名。类变量名方式访问。【前提是 满足访问修饰符的访问权限和范围】
-
实例变量不能通过类名.类变量名 方式访问。
-
类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了。
-
类变量的生命周期是随类的加载开始,随着类消亡而销毁。
-
类方法
-
介绍
类方法也就静态方法
-
定义语法
访问修饰符 static 数据返回类型 方法名(){ }
static 访问修饰符 数据返回类型 方法名(){ }
-
类方法调用
类名.类方法名 或者 对象名.类方法名
/** *类方法的使用 */ public class StaticMethod { public static void main(String[] args) { Stu tom = new Stu("tom"); Stu.payFee(100); Stu mary = new Stu("mary"); Stu.payFee(200); Stu.showFee(); System.out.println("9 开平方的结果是=" + Math.sqrt(9)); System.out.println(MyTools.calSum(10, 30)); } } class MyTools { public static double calSum(double n1, double n2) { eturn n1 + n2; } class Stu { private String name; private static double fee = 0; public Stu(String name) { this.name = name; } public static void payFee(double fee) { Stu.fee += fee; } public static void showFee() { System.out.println("总学费有:" + Stu.fee); } }
-
类方法注意事项和细节
-
当方法中不涉及到任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率。
比如:工具类中的方法 utils
Math类、Arrays类、Collections 集合类看下源码:
-
在程序员实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用了,比如打印一堆数组,冒泡排序,完成某个计算任务等
-
类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区:类方法中无this的参数普通方法中隐含着this的参数
-
类方法可以通过类名调用,也可以通过对象名调用。
-
普通方法和对象有关,需要通过对象名调用,比如对象名.方法名(参数),不能通过类名调用。
-
类方法中不允许使用和对象有关的关键字,比如this和super.普通方法(成员方法)可以。
-
类方法(静态方法)中 只能访问 静态变量 或静态方法 .
-
普通成员方法,既可以访问 非静态成员,也可以访问静态成员。
小结:静态方法,只能访问静态的成员,非静态的方法,可以访问静态成员和非静态成员
-