从零开始学Java,学习笔记Day09

Day09

面对对象

一、继承的使用

理解:子类继承父类所有的属性和方法

注意:

  1. 类与类之间的关系叫做继承
  2. 一个类只能继承另外一个类 – 单继承

应用场景:

  •    编写多个类时,发现多个类有相同的属性和方法,
    
  •    就可以将相同的属性和方法抽取出,放在共同的父类里
    

继承的优缺点:

  •    优点:减少了代码的冗余
    
  •    缺点:增加了类关系的复杂度
    

需求:创建中国人和日本人的类,并且创建对象、操作对象

分析:

  • 人类:

    • 属性:姓名、性别、年龄

    • 方法:吃饭、睡觉

  • 中国人类 继承 人类

    • 属性:身份证

    • 方法:打太极

父类

public class Person {

	String name;
	char sex;
	int age;
	
	private String field = "父类私有化的成员变量";
	
	public String getField() {
		return field;
	}
	
	public void setField(String field) {
		this.field = field;
	}

	public Person() {
		System.out.println("父类的构造方法");
	}
	
	public void eat() {
		System.out.println(this.name + "吃饭");
	}
	
	public void sleep() {
		System.out.println(this.name + "睡觉");
	}
}

子类

public class Chinese extends Person{

	String id;
	
	public Chinese() {
		//默认实现:调用父类非私有化的无参构造
		//super();
		System.out.println("子类的构造方法");
	}
	
	public void playTaiJi(){
		System.out.println("中国人打太极");
	}
}

测试类

public static void main(String[] args) {
    
    //创建中国人对象
    Chinese c = new Chinese();
    //设置父类成员属性
    c.name = "蔡徐坤";
    c.sex = '男';
    c.age = 23;
    //设置子类成员变量
    c.id = "123456";
    //获取父类成员变量
    System.out.println(c.name);
    System.out.println(c.sex);
    System.out.println(c.age);
    //获取子类成员变量
    System.out.println(c.id);
    //调用父类成员方法
    c.eat();
    c.sleep();
    //调用子类成员方法
    c.playTaiJi(); 
}

继承的深入

  1. 创建子类对象时,是否会调用父类构造方法?

    会的

  2. 创建子类对象时,先调用父类构造方法还是先调用子类构造方法?

    先调用子类的构造方法

  3. 创建子类对象时,先完成父类构造方法还是先完成子类构造方法?

    先完成父类的构造方法

  4. 创建子类对象时,会不会创建父类对象?

    不会

  5. 创建子类对象时,为什么会调用父类的构造方法?

    创建子类对象,调用父类方法的目的是在子类对象中开辟空间存储父类的成员属性

  6. 子类能否继承父类私有化的属性和方法?

    可以,但是不能直接使用,必须间接调用(私有化属性设置对应的公有化的方法,调用公有化的方法去操作私有化的属性)

二、super

理解:super表示父类的

作用:

  • super.属性:在子类中,调用父类非私有化的成员变量
  • super.方法:在子类中,调用父类非私有化的成员方法
  • super():在子类中的构造方法的第一句调用父类非私有化的构造方法

三、重写/复用

理解:将父类的方法在子类中重新写一遍

应用场景:父类方法不满足子类需求时,且父类方法不能被改动,就可以考虑在子类中重写

条件:

  1. 在子类中重写
  2. 返回值、方法名、参数列表必须和父类重写的方法一致
  3. 访问修饰符不能比父类的方法更严格
public class Person {

	private String name;
	private char sex;
	private int age;
	
	public Person() {
	}
	
	public Person(String name, char sex, int age) {
		this.name = name;
		this.sex = sex;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void eat() {
		System.out.println(this.name + "吃饭");
	}
	
	public void sleep() {
		System.out.println(this.name + "睡觉");
	}
}

public class Chinese extends Person{

	private String id;
	
	public Chinese() {
	}
	
	public Chinese(String id) {
		//super(); -- 默认实现:调用父类非私有化的构造方法
		this.id = id;
	}

	public Chinese(String name, char sex, int age, String id) {
		super(name, sex, age);
		this.id = id;
	}
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void playTaiJi(){
		System.out.println(super.getName() + "打太极");
	}
	
	//@Override - 重写的注解,描述该方法是重写父类的
	@Override
	public void eat() {
		System.out.println(super.getName() + "吃山珍海味");
	}
}
import test03.Chinese;

public class Test01 {

	public static void main(String[] args) {

		//创建中国人的对象
		Chinese c = new Chinese("蔡徐坤", '男', 23, "1234567890");

		c.eat();
		c.sleep();
		c.playTaiJi();
	}
}

四、访问修饰符

理解:定义类、接口、属性、方法的访问权限

分类:

  • private(私有的)
  • default(默认的)
  • protected(受保护的)
  • public (共有的)

注意:

  1. 类和接口上只能使用public和默认的访问修饰符
  2. 属性和方法都可以使用四个访问修饰符修饰
访问修饰符本类中本包中其他包的子类其他包
privateOK
默认的OKOK
protectedOKOKOK
publicOKOKOKOK

经验:

  • 属性一般使用private修饰
  • 属性要想给子类使用,一般使用protected
  • 方法一般使用public修饰
  • 方法要想只在该类中使用,一般使用private
  • 方法要想给子类使用/重写,一般使用protected

五、Object类

Object了解

理解:Object是所有类的超类/基类,如果一个类没有明确继承的类,该类默认继承Object

equals()

理解:判断两个对象的内存地址是否相同

public static void main(String[] args) {

    Object obj1 = new Object();//0x001
    Object obj2 = new Object();//0x002

    System.out.println(obj1 == obj2);//false
    System.out.println(obj1.equals(obj2));//false
    /**
		 * Object类 -- equals底层:
		 * 		public boolean equals(Object obj){
		 * 			//		obj1 == obj2
		 * 			return (this == obj);
		 * 		}
		 */


}
getClass()

前言:使用到类,JVM会将该类的class文件加载到方法区(1次),并在堆中创建class对象,所以class对象是唯一的

理解:获取到该类的class对象

public static void main(String[] args) {

    Object obj1 = new Object();//0x001
    Object obj2 = new Object();//0x002

    Class<? extends Object> class1 = obj1.getClass();//获取Object类的class对象
    Class<? extends Object> class2 = obj2.getClass();//获取Object类的class对象

    System.out.println(class1 == class2);//true
    System.out.println(class1.getName());//java.lang.Object
    System.out.println(class2.getName());//java.lang.Object


}
hashCode()

理解:获取对象的hash值(hash值=内存地址+散列算法)

public static void main(String[] args) {

    Object obj1 = new Object();//0x001
    Object obj2 = new Object();//0x002

    int hashCode1 = obj1.hashCode();
    int hashCode2 = obj2.hashCode();
    System.out.println(hashCode1);
    System.out.println(hashCode2);
}
toString()

理解::将对象转换为字符串

public static void main(String[] args) {

    Object obj = new Object();

    //java.lang.Object@15db9742
    System.out.println(obj);//打印对象,默认调用toString()
    System.out.println(obj.toString());

    /**
		 * Object类的toString()底层:
		 * 
		 * 	public String toString(){
		 * 	
		 * 		//     java.lang.Object        @    15db9742
		 * 		return getClass().getName() + "@" + Integer.toHexString(hashCode());
		 * 	}
		 */

}

Object类的使用

  • equals():判断两个对象是否相同,不同的子类有着不同的判断规则,子类重写即可
  • getClass():先不管,在反射的技术点中学习
  • hashCode():先不管,在集合的技术点中学习
  • toString():将对象转换成字符串,不同的子类有着不同的属性,子类重写即可

编写类的步骤:

  1. 属性
  2. 私有化属性
  3. 无参构造
  4. 有参构造
  5. get/set方法
  6. 独有的方法
  7. 重写equals
  8. 重写toString
public class User {

	private String username;
	private String password;
	private String nickName;
	
	public User() {
	}

	public User(String username, String password, String nickName) {
		this.username = username;
		this.password = password;
		this.nickName = nickName;
	}

	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 String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	
	//obj - 0x002
	@Override
	public boolean equals(Object obj) {
		
		//先判断两个对象内存地址是否相同
		//user1 == user2
		//0x001 == 0x002
		if(this == obj){
			return true;
		}
		
		//user - 0x002
		User user = (User) obj;
		
		//0x001.username.equals(0x002.username)
		if(this.username.equals(user.username)){
			return true;
		}
		return false;
	}
	
	@Override
	public String toString() {
		return username + " -- " + password + " -- " + nickName;
	}
}

public class Test01 {
    public static void main(String[] args) {

        User user1 = new User("147258369", "123123", "蔡徐坤");//0x001
        User user2 = new User("147258369", "123123", "蔡徐坤");//0x002

        System.out.println(user1.equals(user2));//true

        System.out.println(user1);
        System.out.println(user2);
    }
}

Object的使用 – 深入String底层原理

public class MyString {

	private final char[] value;
	
	public MyString(String original) {
		//toCharArray() -- 将字符串转换为字符数组
		value = original.toCharArray();
	}
	
	@Override
	public boolean equals(Object obj) {
		
		if(this == obj){
			return true;
		}
		
		MyString my = (MyString) obj;
		char[] v1 = this.value;//my1.value -- ['a','b','c']
		char[] v2 = my.value;//my2.value   -- ['a','b','c']
		
		int length = v1.length;
		if(length == v2.length){
			for (int i = 0; i < length; i++) {
				if(v1[i] != v2[i]){
					return false;
				}
			}
			return true;
		}
		return false;
	}
	
	@Override
	public String toString() {
		String str = "";
		for (char element : value) {
			str += element;
		}
		
		return str;
	}
}
public class Test01 {

	public static void main(String[] args) {
		
		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1 == str2);//false
		System.out.println(str1.equals(str2));//true
		
		System.out.println(str1);//abc
		System.out.println(str2);//abc
		
		System.out.println("---------------------------------");
		
		MyString my1 = new MyString("abc");
		MyString my2 = new MyString("abc");
	
		System.out.println(my1 == my2);//false
		System.out.println(my1.equals(my2));//true
		
		System.out.println(my1);//abc
		System.out.println(my2);//abc
	}
}

总结

  1. 继承的使用
  2. 继承的深入
  3. super
  4. 重写
  5. 访问修饰符 – 做实验
  6. Object(了解、使用、MyString)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值