java之类与对象详解

对象的4大特性

抽象

把现实生活中的某一类东西提取出来,用程序代码来表示,抽象出来的程序代码叫做类或接口。
抽象分为两个部分:数据(可以理解为现实事务的特征)抽象和行为抽象。

  • 数据抽象:现实生活中事务的特征,对应类中的属性(比如现实生活中人有眼睛、鼻子等,抽象到类中就是眼睛属性、鼻子属性)。
  • 行为抽象:现实生活中事务的行为,对应类中的方法(比如现实生活中人会吃饭、睡觉等,抽象到类中就是吃饭方法、睡觉方法)。

封装

把数据和行为集中到一个类中(用来提供给外部使用)。

继承

继承主要是为了实现代码的重用。父类中有一些属性和方法,子类继承父类,那么子类中也会有父类中的这些属性和方法。与此同时,子类也可以添加自己特有的属性,如果子类中方法的实现和父类不一样,子类也可以重写父类的方法。

多态

可以理解为不同对象同种行为的不同表现。在java中的表现为方法的重写、方法的重载以及动态绑定都为多态。

Object类中常见方法

object类是所有类的父类,里面有一些常用的方法。

equals()

我们知道所有的对象都拥有标识(内存地址)和状态(数据),同时“==”比较两个对象的的内存地址,所以说使用Object的equals()方法是比较两个对象的内存地址是否相等,即 object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。
但如果我们不想在比较的时候比较两个对象的引用地址就需要重写equals方法。

hashCode()

hash值:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
为什么要重写hashcode()方法?其实当 equals 方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
我们是希望两个对象如果相等,那么在使用 hashSet 存储时也能认为这两个对象相等。
hashCode 是用于散列数据的快速存取,如利用 HashSet/HashMap/Hashtable 类来存储数据时,都会根据存储对象的 hashCode 值来进行判断是否相同的。

重写hashCode()和equals()

public class Student {
	private String name; //姓名
	private String sex; //性别
	private String age; //年龄
	private float weight; //体重
	private String addr; //地址
	
	// 重写hashcode方法
	@Override
	public int hashCode() {
		int result = name.hashCode();
		result = 17 * result + sex.hashCode();
		result = 17 * result + age.hashCode();
		return result;
	}
 
	// 重写equals方法
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Student)) {
       // instanceof 已经处理了obj = null的情况
			return false;
		}
		Student stuObj = (Student) obj;
		// 地址相等
		if (this == stuObj) {
			return true;
		}
		// 如果两个对象姓名、年龄、性别相等,我们认为两个对象相等
		if (stuObj.name.equals(this.name) && stuObj.sex.equals(this.sex) && stuObj.age.equals(this.age)) {
			return true;
		} else {
			return false;
		}
	}
}

clone()

public Person{
	public String name;
	public int age;
	public Person(String name,int age){
   	this.name=name;
   	this.age=age;
   }
}
Person p = new Person("张三",18);
Person p1 = p;

此时p1只是p的一个引用。

Person p = new Person("张三",18);
Person p1 = (Person)p.clone();

这么一调用之后就复制出了新对象。

浅拷贝

  • 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递。
  • 对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递。

注意:String类型通过常量赋值时相当于基本数据类型,通过new关键字创建对象时便是引用数据类型

实现对象拷贝的类,需要实现 Cloneable 接口,并覆写 clone() 方法

public class Student implements Cloneable {

    private String name;
    private int age;
    /**
     *  重写clone()方法
     * @return
     */
    @Override
    public Object clone() throws CloneNotSupportedException{
            return super.clone();
    }
}

深拷贝

下面介绍一下基本深拷贝的代码 很短 : 你一定主要 主类包装了多少其他的引用类型的其他类,那么其他必须都要实现Cloneable 接口 以及clone 方法。

public class Student implements Cloneable {

   public User user;
   public Data data;
   /**
    *  重写clone()方法
    * @return
    */
   @Override
   public Object clone() throws CloneNotSupportedException{
   		Student s=(Student)super.clone();
   		s.user=(User)user.clone();
   		s.data=(Data)data.clone();
           return s;
   }
}

finalize()

垃圾回收器准备释放内存的时候,会先调用finalize()。

内部类

普通内部类

public class Outer{
   public class Inner{

   }
}
  • 内用外随意访问。
  • 外用内,需要创建对象。

匿名内部类

接口名 inter=new 接口名(){
   //覆写所有抽象方法
}

类的转型

向上转型

Animal cat = new Cat();

此时cat向上转型成Animal ,注意此时cat不能调用Cat类中独有的方法。

向下转型

类似于强制转换。

instanceof

当对象向上转型后如何判断他的向下转型的对象是什么呢,这就得用到instanceof

animal instanceof Dog

例子中的意思就是判断这个animal对象是不是dog类。

发布了23 篇原创文章 · 获赞 1 · 访问量 511

猜你喜欢

转载自blog.csdn.net/qq_38783257/article/details/103570540