1.多态向下转型
多态中转型如果不对则报错ClassCaseException
public class Test{
public static void main(String[] args){
//向上转型
Animal animal = new Cat();
//向下转型(必须先向上转完才能向下转型)
Cat cat = (Animal) animal;
//多态中常用instanceof来判断对象是否由某个类实例化而来
//if(animal instanceof Cat/Animal){
// Cat cat = (Animal) animal;
//}
}
}
//父类
class Animal{
}
//子类
class Cat extends Animal{
}
隐式多态:
父类中子类调用方法或属性
public class Poly_02 {
public static void main(String[] args) {
Sub sub = new Sub();
// System.out.println(sub.i);
sub.m1();
// sub.m2();
}
}
class Sup {
int i = 2;
public void m1() {
/**
* this : 保存了当前对象的内存地址,是对象中第一个成员变量
* 当前类 有是什么 : 指的是this出现在哪个类中,当前类就是哪个类
* this的类型 是什么 才能保存当前类的对象
* 可以保存当前类对象的类型,只有当前类类型和其父类类型
* 如果是父类类型的话,就会发生多态,会丢失子类特有的属性
* 由于this可以调用所有属性,所以this一定是当前类类型, 也就是 Sup
* Sup this;
* this 出现在成员方法中,谁调用这个方法,this就保存谁的地址
* 最终通过sub对象调用(继承) , 所以 this就指向sub对象
* Sup this = sub;
*/
System.out.println(this.i);
System.out.println(i);
this.m2();
m2();
}
public void m2() {
System.out.println("父类m2");
}
}
class Sub extends Sup {
int i = 22;
public void m2() {
System.out.println("子类m2");
}
}
2.抽象
抽象类不能被new创建对象,但可以被继承(因为可以被继承所以抽象类中有构造方法),抽象类修饰符为abstract,抽象方法(一般没有实现方法体,放在子类中去实现)必须放在抽象类中,但抽象类中可以有普通方法,继承抽象类必须重写所有抽象方法。
abstract class Animal {
// 抽象方法,没有方法体
public abstract void eat();
}
// 猫类
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
// 狗类
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
}
3.接口
接口定义使用interface关键词(不能被new创建对象,没有构造器),1.8之前接口中只有抽象方法和常量,1.8及之后接口增加静态方法和成员方法功能。接口解决Java的单继承问题,利用implements去实现接口。接口中没有变量,只有常量用public static final(可省略)修饰
interface Animal {
// 抽象方法,没有方法体
public abstract void eat();
}
// 猫类
class Cat extends Object implements Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
// 狗类
class Dog implements Animal {
public void eat() {
System.out.println("狗吃肉");
}
}
接口和抽象类的区别:能同时使用时优先选择接口,接口能多实现,类只能单继承
4.toString()
Object中的toString()通常输出的是内存地址,当使用时不方便,通常会重写toString()输出需要的值
public class ToString01 {
public static void main(String[] args) {
User u1 = new User("admin", "root");
System.out.println(u1);
}
}
class User {
public String toString() {
return "我的用户名是 : "+username+" , 我的密码是 : "+password;
}
private String username;
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public User() {
super();
}
}
5.equals()
object中的equals()实现是利用==
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
}
==:基本类型比较的是值,应用类型比较的是地址(我们通常需要比较引用类型的内容,因此需要重写equals())
public class Equels01 {
public static void main(String[] args) {
Student s1 = new Student(1001, "张三", 18);
Student s2 = new Student(1001, "张三", 18);
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
// 判断要比较的对象,是否是当前类对象
if (obj instanceof Student) {
Student s1 = (Student) obj;
if (s1.id == this.id && this.name.equals(s1.name)) {
return true;
}
}
return false;
}
6.Finalize
// 当一个垃圾被回收的时候,会在回收前自动调用该对象的finalize方法,进行收尾工作
// 一般做一些关闭资源等操作
// 垃圾:当一个对象,没有任何引用指向他的时候,该对象被视为垃圾数据,等待垃圾回收器回收
// 如果我们手动调用finalize方法,那么只是一个方法调用而已,并不会回收
// finalize方法并没有回收垃圾的功能,只是在回收前,会自动调用执行而已
public class Fianlize {
public static void main(String[] args) {
Fianlize f = new Fianlize();
f = null;
// 程序员可建议垃圾回收器进行回收
// for (int i = 0; i < 100000; i++) {
// System.gc();
// }
// 垃圾比较多的时候,也会触发自动回收
for (int i = 0; i < 10000000; i++) {
new Fianlize();
}
}
@Override
protected void finalize() throws Throwable {
System.out.println(this + " : 我要被回收了");
}
}