JavaSE_06_面向对象

继承的定义

1.什么是继承?
所谓继承就是在原有类的基础之上派生出一个新的类的,这个过程称之为继承
原有类:父类
新的类:子类    
  
---------------------------------------------------------------------
2.那继承有什么用呢?
   1.可以减少代码冗余,提高开发效率
   2.提高程序的可扩展性
   3.因为有了继承才有了后面的多态 
  
3.特点:
子类一旦继承了父类,就会拥有的父类的内容(属性和方法)
注意:
<1>.子类无法继承父类的构造方法
<2>.子类无法继承父类的私有属性和方法(不全面,受到访问修饰符权限的限制)
  子类可以通过继承的setter()getter()方法来操作属性。
<3>.如果2个类在不同包下,使用的是默认修饰符修饰的属性或者方法也无法继承(访问权限的影响)
<4>.子类虽然无法继承父类的构造方法,但是可以调用父类的构造方法,但是必须在子类的构造方法中的第一行。
    
    
继承的代码实现:
继承的关键字:extends 
1.设计父类 
Person (将学生和老师的一些公共的部分全部封装到父类中)  
    public class Person {
	private int id;
	private String name;
	private int age;
	private char sex;
	private String phoneNum;
	private String address;
	...
 }     
Student (独有的属性或在方法)
    public class Student extends Person{
		...        
    }
测试:
public static void main(String[] args) {
		Student stu=new Student();
		stu.setId(1);
		stu.setName("张三");
		stu.setPhoneNum("111");
		stu.setAddress("浦东新区");
		stu.setAge(24);
		stu.setSex('男');
		stu.show();
}

记住:
1.创建对象的时候,如果没有改写构造方法,那么系统会默认调用默认构造(无参构造),一旦改写了构造方法,默认构造失效,将无法使用(为了防止默认构造失效,一般会给类提供一个无参构造,然后再去改写)
    
2.实际上在子类的构造方法的第一句系统会默认调用父类的默认构造(无参构造),当然也可以在子类的构造方法中调用改写之后的父类构造。super(...)
    
Teacher(独有的属性或者方法)   省略 
    
扩展1:针对属性而言 子类继承了父类属性,但是如果在子类中又重新定义了这些被继承的属性,那么被继承的属性将会被隐藏。(遵循就近原则)
    
<1>.设计一个Pet类(id,nickName,age,health(1-100))
    设计一个Dog类 show() 打印详细信息
    设计一个Cat类 show() 打印详细信息
    

继承的方式

Java类只支持单继承?(一个子类只能有一个父类)
为什么?
子类一旦继承父类 那么就会拥有父类的方法或者属性,不仅如此在子类的构造方法的第一句会调用父类的构造方法。
假设一个子类拥有多个父类,那么子类构造方法的第一句到底调用哪个父类的构造方法?
public class A{
	public void method(){
        ...
        Sout...(A...);
    }
}

public class B{
    public void method(){
        ...
        Sout...(B...);
    }
}

假设可以出现多个父类
public class C extends A,B{
    
}
注意:1个子类虽然只能有一个父类,但是1个父类可以有多个子类。
Java类只支持单继承(正确)   
Java只支持单继承(错误)
Java支持单继承(正确)
           
Java类支持多层继承:最终子类拥有整个继承体系中所有的内容(所能够继承的内容)

扩展:Java;类个顶级父类Object类(它是所有类的父类)
            

this关键字

this:当前类的对象 (对象的地址)
User (id,name) 
User user=new User(1,"jack");

super关键字

super:父类对象 (指向父类的对象的地址)
Person(phoneNum) 父类
User (id,name) extends Person 子类
User user=new User(1,"jack"); 创建了一个子类
user.setPhoneNum("110");

this和super内存图解

2.png

this:当前类的对象
<1>.通过this去调用属性或者方法,先去子类中寻找属性或者方法,找到了指向找到的属性或者方法,找不到就会到父类中寻找。

super:父类对象
<2>.直接到父类中寻找相应的属性或者方法

重写

重写是针对方法
1.重写的概念:在子类中将继承自父类的方法进行重新改写的过程,称之为重写。
2.重写的前提条件:必须要有继承关系
3.特点:子类一旦重写了父类的方法,那么子类对象调用方法的时候,调用的重写之后的方法,父类方法将会被隐藏。

4.重写与重载之间区别:
重载:
	<1>.在同一个类中,存在多个方法名字相同。
	<2>.重载与访问修饰符无关
	<3>.返回值可以不同。
	<4>.参数必须不同
重写:
	<1>.在继承关系中的子类中,将继承自父类中的方法进行重新改写的过程。
	<2>.子类的访问修饰不能严于父类(子类的访问修饰符不能比父类小)
	<3>.返回值必须与父类属于同类型
	<4>.参数必须相同。
----------------------------------------------------------------------------------
<1>.设计一个Pet (show(),eat(),sound())...
	设计一个Cat类以及一个Dog类完成方法重写。(打印的内容自己定义).

重写的内容补充

重写Object中一些常用方法:
toString();
@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", userPass=" + userPass + "]";
	}
equals()hashcode()方法: 
重写equals方法就必需重写hascode方法:
    public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((userName == null) ? 0 : userName.hashCode());
		result = prime * result + ((userPass == null) ? 0 : userPass.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (id != other.id)
			return false;
		if (userName == null) {
			if (other.userName != null)
				return false;
		} else if (!userName.equals(other.userName))
			return false;
		if (userPass == null) {
			if (other.userPass != null)
				return false;
		} else if (!userPass.equals(other.userPass))
			return false;
		return true;
	}


------------------------------------------------------------------------------------
hashCode相等2个对象  equals不一定相等
equals相等2个对象   hashcode一定相等
HashSet(不可重复)
    1.先判断hashCode是否相等,如果hashcode相等,判断equals是否相等
    2.hascode相等,判断equals有可能不相等...

final 关键字

1.fianl关键字修饰变量那么这个变量将会变成一个常量(不可以修改的数据)
一般与static合起来用。 (命名规则:字母全部大写,单词与单词之间用_隔开)。
final static int DAY_WEEK=10;
2.final关键字修饰方法,说明方法不可以重写  
3.final关键字修饰类,说明这个类不能被继承 (不能做父类了)

向上转型与向下转型

向上转型:(默认转换)
小的类型转大的类型(范围小的--->范围大的)===>(子类--->父类)
Pet pet=new Cat();
//1.注意点: 转型之后会导致数据的丢失(将不是父类的内容全部丢失),重写自父类的内容保留下来

向下转型:(强制转换)
大的类型转小的类型(范围大的--->范围小的)===>(父类--->子类)
Cat cat=(Cat)new Pet();

instanceof 判断某个实例是否属于指定的类型,如果属性指定的类型返回true 不属于返回false
//1.向上转型 (多态中应用)
		Pet pet=new Cat();
		pet.eat();
		pet.sound();
		
		//2.向下转型 (属于同一类型才能强制转换)
		/*Dog dog=(Dog) pet;
			dog.eat();*/
		//3.注意必须属于同类型,才可以转换
		Cat cat=(Cat) pet;
		cat.eat();
		cat.sound();
		System.out.println(pet instanceof Pet);//true
		System.out.println(pet instanceof Cat);//true
		System.out.println(pet instanceof Dog);//false    

类的初始化顺序

阶段一:代码块

public class Son{
	static{
		//静态代码块
	}
    {
        //普通代码块
    }
    public Son(){
        //构造方法
    }
}
静态代码块>普通代码块>构造代码块

阶段二: 熟悉、方法和代码块

public class Son{
    int age; //普通属性
    static String name;//静态属性
    public void method1(){
        //普通方法
    }
    public static void method2(){
        //静态方法
    }
	static{
		//静态代码块
	}
    {
        //普通代码块
    }
    public Son(){
        //构造方法
    }
}
1.静态资源(静态属性,静态代码块,谁先声明谁先加载>静态方法)>
2.非静态资源(普通属性,普通代码块,谁先声明谁先加载>普通方法)>
3.构造方法

阶段三: 父类与子类代码块

设计父类
public class Father {
	static {
		System.out.println("父类静态代码块...");
	}
	{
		System.out.println("父类的普通代码块...");
	}
	public Father() {
		System.out.println("父类的构造代码块...");
	}
}
设计子类
public class Son extends Father{
	{
		System.out.println("子类普通代码块...");
	}
	static {
		System.out.println("子类静态代码块...");
	}
	public Son() {
		System.out.println("子类代码块...");
	}
	
}
父类的静态代码块-->子类的静态代码块--->父类的普通代码块--->父类构造代码块---->子类的普通代码块
---->子类的构造代码块.

阶段四: 终极版本

父类与子类的熟悉、方法和代码块

设计子类:
    public class Son extends Father{
	static String pass;
	int num;
	{
		System.out.println("子类普通代码块...");
	}
	static {
		System.out.println("子类静态代码块...");
	}
	
	
	public Son() {
		System.out.println("子类构造代码块...");
	}
	
	public static void  method3() {}
	public void method4() {}
}
设计父类
    public class Father {
	static String name;
	int age;
	
	static {
		System.out.println("父类静态代码块...");
	}
	{
		System.out.println("父类的普通代码块...");
	}
	public Father() {
		System.out.println("父类的构造代码块...");
	}
	public static void method1() {
		
	}
	public void method2() {
		
	}
}
父类的静态代码块,父类静态属性-->子类的静态代码块,子类静态属性
--->父类的静态方法--->子类的静态方法--->父类的普通代码块,父类的普通属性
--->父类的普通方法--->父类构造代码块---->子类的普通代码块,子类普通属性
--->子类的普通方法---->子类的构造代码块。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值