其他(会用即可)
快捷创建子类:类名后快捷键:alt+enter->Create Subclass
重写父类方法:(IDEA快捷键:alt+insert->Override-Method)
重写Object类部分方法的快捷键:alt+insert->equals、toString、hashCode
继承(理解)
看下面干货分享
/**
* 继承.父类
* 存放共有的属性+行为
*/
public class Person {
private String name;
private int age;
private String sex;
public Person(String name, int age, String sex) {
System.out.println("\t\t\t\t\t我是父类的有参构造器");
this.name = name;
this.age = age;
this.sex = sex;
}
public Person() {
System.out.println("\t\t\t\t\t我是父类的无参构造器");
}
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void selfIntroduction(){
System.out.println("我就是一个普通老百姓");
}
}
/**
* SportsMan 继承中的子类,运动员类
* 存放特有的属性+行为
*/
public class SportsMan extends Person{
private String sportEvent;//运动项目
private String bestResult;//最好成绩
public String getSportEvent() {
return sportEvent;
}
public void setSportEvent(String sportEvent) {
this.sportEvent = sportEvent;
}
public String getBestResult() {
return bestResult;
}
public void setBestResult(String bestResult) {
this.bestResult = bestResult;
}
@Override
public void selfIntroduction() {
/*super.selfIntroduction();*/
/*
调用继承过来的属性/资源 name、this.name、super.name
*/
System.out.println("大家好,我叫"+super.getName());
System.out.println("今年"+this.getAge());
System.out.println("我擅长的运动项目是:"+sportEvent);
System.out.println("历史最好的成绩是:"+getBestResult());
}
}
/**
* Actor 继承子类,演员类
* 存放特有的属性+行为
*/
public class Actor extends Person{
private String graduateInstitutions;//毕业院校
private String masterWork;//代表作
//子类重写父类的构造方法
public Actor(String name, int age, String sex, String graduateInstitutions, String masterWork) {
// super(name, age, sex);//父类必须有有参构造
System.out.println("\t\t\t\t\t我是子类有参构造器");
super.setName(name);//父类必须有无参构造
super.setAge(age);
super.setSex(sex);
this.graduateInstitutions = graduateInstitutions;
this.masterWork = masterWork;
}
public Actor() {
System.out.println("\t\t\t\t\t我是子类无参构造器");
}
public String getGraduateInstitutions() {
return graduateInstitutions;
}
public void setGraduateInstitutions(String graduateInstitutions) {
this.graduateInstitutions = graduateInstitutions;
}
public String getMasterWork() {
return masterWork;
}
public void setMasterWork(String masterWork) {
this.masterWork = masterWork;
}
//快捷键:
@Override
public void selfIntroduction() {
System.out.println("大家好!我是"+getName());
System.out.println("今年"+getAge());
System.out.println("我毕业于:"+graduateInstitutions);
System.out.println("代表作有:《"+masterWork+"》");
}
}
import com.jr.curriculum.act.Actor;
import com.jr.curriculum.act.Person;
import com.jr.curriculum.act.SportsMan;
public class Demo1 {
public static void main(String[] args) {
Person person = new Person();
person.selfIntroduction();
System.out.println("=========================");
SportsMan sportsMan = new SportsMan();
/*【赋值方式一】
set..()进行赋值
*/
sportsMan.setName("刘小翔");
sportsMan.setAge(23);
sportsMan.setSex("男");
sportsMan.setBestResult("22秒30");
sportsMan.setSportEvent("二百米短跑");
sportsMan.selfIntroduction();
System.out.println("=========================");
/*【赋值方式二】
构造器赋值
*/
Actor actor = new Actor("章依",27,"女","北京电影学院","寄往天国的家书");
actor.selfIntroduction();
}
/*
面向对象思想:封装(安全性,隐私属性,公有方法)、继承(代码的重用)、多态
变量:存储信息的重用
方法:功能代码的重用
继承:多个关联类中,属性和方法的重用
【继承】
1.好处:代码的重用
2.如何实现继承:
第一步:从多个关联类中,提取出相同的属性和共同的行为,放到一个单独的类里,这个单独的类就叫父类(基类)(超类)
第二步:将各自特有的属性和行为保留在各自的类中,那么这些各自的类就叫子类(派生类)
第三步:在子类的类名后实现继承,公式:【子类名 extends 父类名】
3.继承的分类:
直接继承:extends 父类 --(extends后面只能写一个类)
间接继承:子类 --(间接继承于Object类)
4.继承的特性:
单根性:子类有且只有一个父类
传递性:A继承B,B继承C,A对象可以使用C中的属性和行为
5.子类可以继承父类的哪些资源信息呢?
【不能继承的】子类不能继承父类的构造器,但是子类可以调用父类的构造器
【继承的】除了构造器,父类的资源子类都能继承,但是private虽然继承了,但权限问题可能无法使用
【是否可用】 本类 同包子类 同包非子类 不同包子类 不同包非子类
public √ √ √ √ √
protected √ √ √ √ ×
默认的 √ √ √ × ×
private √ × × × ×
6.子类如何使用父类继承的资源:
1)直接用:属性名 方法名()
2)通过this关键字使用:this.属性名、this.方法名()
3)通过super关键字使用:super.name、super.方法名()
7.子类在调用继承过来的父类方法时,发现父类方法体的解决方案不适用了。
子类可以重写继承过来的父类方法。
【重写】在子类中,方法名必须相同,参数列表必须相同,返回值类型子类不能大于父类,访问修饰符子类不能小于父类(只取好的情况)
【重载】同一个类下,方法名必须相同,参数列表必须不同(个数、类型、位置),与返回值类型和访问修饰符无关的两个或两个以上的方法
8.super关键字:
1)子类可以通过super关键字,调用父类的资源信息
2)super代表父类
用途:
super.属性、super.方法()、构造器:super()、super(参数列表)
【1】子类构造一定调用父类构造:
调用父类构造有两种方式:
默认:程序会自动帮忙调用父类无参构造;
手动:使用super关键字:
super();表示调用父类的无参构造
super(name,age,gender);表示调用父类的有参构造
===扩展,super()调用父类构造器,必须位于子类构造器的第一行
this()调用自身构造器,必须位于子类构造器的第一行 ==解决方案:错开调用
9.继承状态下子类构造器的执行顺序,当我们调用子类构造器时
程序会找到最顶级父类,先执行顶级父类的构造器
(如果父类有多个构造器,执行子类调用的构造(默认调用无参构造,手动调用指定的构造器))
,再执行一级父类的构造器,二级父类构造器,,,直到子类构造器。
此时子类对象才算创建成功!
*/
}
Object类(要会重写equals、toString、hashCode)
import java.util.Objects;
public class Demo2 {
String name;
String idCard;
public Demo2(String name, String idCard) {//有参构造
this.name = name;
this.idCard = idCard;
}
public Demo2() {
}
public static void main(String[] args) {
Demo2 demo2 = new Demo2("惠常哲","220211200103070915");
System.out.println(demo2.toString());
System.out.println(demo2);//引用数据类型默认调用toString()方法
Demo2 demo1 = new Demo2("惠常哲","220211200103070915");
System.out.println(demo2.equals(demo1));//不重写是false,下面重写后是true
String a = new String("12");
String b = new String("12");
System.out.println(a.equals(b));//true
System.out.println("hashCode值为:"+demo1.hashCode());//重写后hashCode值一致
System.out.println("hashCode值为:"+demo2.hashCode());
}
public String toString() {//重写Object类的toString方法
return "我是Demo2对象,姓名是:"+name;
}
public boolean equals(Object demo2) {//重写equals方法,改里面类型就是重载了
if (this == demo2){//地址一样
return true;
}
if (demo2 instanceof Demo2){//判断是不是这个类型
if (this.name.equals(((Demo2) demo2).name) && this.idCard.equals(((Demo2) demo2).idCard)){//姓名和身份证号一样
return true;
}
}
return false;//其他情况返回false
}
public int hashCode() {
return this.name.hashCode()+this.idCard.hashCode();
}
/*
【顶级父类:Object类】
1.包名:java.lang(程序自动导入)
2.public class Object 公有类
3.构造器:公有无参构造
4.Object类没有属性
5.11个方法:
【重点掌握】 【反射时讲】 【线程时讲】 垃圾回收机制 克隆(用不到了)
equals() getClass() notify() finalize() clone()
hashCode() notifyAll()
toString() wait()
wait(long timeout)
wait(long timeout,int nano)
【介绍toString方法】
源码:return getClass().getName() + "@" + Integer.toHexString(hashCode());
getClass().getName():获取当前所在类的全局限定名(就是包名.类名)
Integer.toHexString(hashCode()):将hashCode的值转成十六进制值
一般在程序中,调用对象的toString()为了查看该对象的所有属性信息
所以我们有必要重写Object类继承过来的toString()方法
注意:System.out.println(对象);==System.out.println(对象.toString());
IDEA快捷键:alt+insert选toString()
【介绍equals方法】
Object的源码:
public boolean equals(Object obj) {
return (this == obj);
}
String的源码:(根据jdk版本不一样而不同)
public boolean equals(Object anObject) {
if (this == anObject) {//判断地址是不是一样
return true;
}
if (anObject instanceof String) {//判断传进来的类型是不是字符串类型
String aString = (String)anObject;//强转成字符串类型
if (coder() == aString.coder()) {//比十六进制的Code码
return isLatin1() ? StringLatin1.equals(value, aString.value)
: StringUTF16.equals(value, aString.value);
}
}
return false;
}
一般情况下:调用equals()方法是用来比较两个对象之间属性值是否相同,相同返回true,不同返回false
================说明我们要重写equals()方法
【hashCode方法】
源码:public native int hashCode();
介绍:底层采用哈希算法,将程序中对象的内存地址转换成hash值。
一般情况下,重写equals()后,也要重写hashCode()方法
扩展:集合讲,比较对象是否相同
先判断两个对象的hashCode()值是否相同,hashCode值不同则认为是不同的对象,直接存储到集合里。
当hashCode值相同时(因为hashCode有可能是多个数相加,所以值还是可能一致的)
要再用equals方法进行比较,如果为true则是相同对象,不进行存储,否则为false进行存储
*/
}
类和类之间的关系(面试提问要能答出来)
public class Demo3 {
/*
【类和类之间的关联关系】
分为六种:
1.继承关系:类 extends 类
2.实现关系:类 implements 接口
3.依赖关系:类A是类B某一方法的参数
4.关联关系:类A是类B的属性
5.聚合关系 6.组合关系 代码体现时都是关联关系
*/
}
关系 | 说明 |
---|---|
继承关系 | 类 extends 类 |
实现关系 | 类 implements 接口 |
依赖关系 | 类A是类B某一方法的参数 |
关联关系 | 类A是类B的属性 |
聚合关系 | |
组合关系 |
继承(重点)
继承的好处:
提高代码的复用性,便于代码的扩展
复用性体现在:(父类定义的内容,子类可以直接拿过来用就可以了,不用代码上反复重复定义了)
如何实现继承:
- 从多个关联类中,提取出相同的属性和共同的行为,放到一个单独的类里,这个单独的类就叫父类(基类)(超类)
- 将各自特有的属性和行为保留在各自的类中,那么这些各自的类就叫子类(派生类)
- 在子类的类名后实现继承,公式:【子类名 extends 父类名】
继承的分类:
直接继承:extends 父类 --(extends后面只能写一个类)
间接继承:子类 --(间接继承于Object类)
继承的特性:java是单继承
单根性:一个子类只能有一个直接父类。 但是可以间接的继承自其它类。可通过多层继承、内部类、接口间接继承
,一个父类可以有多个子类。
传递性:A继承B,B继承C,A对象可以使用C中的属性和行为。Object类是所有类的根基父类。
所有的类都直接或者间接的继承自Object
子类可以继承父类的哪些资源
【不能继承的】子类不能继承父类的构造器,但是子类可以调用父类的构造器
【继承的】除了构造器,父类的资源子类都能继承
,但是private虽然继承了,但权限问题可能无法使用
父类private修饰的内容,子类实际上也继承
,只是因为封装的特性阻碍了直接调用,但是提供了间接调用的方式,可以间接调用。
子类如何使用父类继承的资源:
1)直接用:属性名 方法名()
2)通过this关键字使用:this.属性名、this.方法名()
3)通过super关键字使用:super.name、super.方法名()
重写(重点)
发生在子类和父类中,当子类对父类提供的方法不满意的时候,要对父类的方法进行重写。
重写与重载的区别:
重载:同一个类下,方法名必须相同,参数列表必须不同(个数、类型、位置),与返回值类型和访问修饰符无关的两个或两个以上的方法
重写:在子类中,方法名必须相同,参数列表必须相同,返回值类型子类不能大于父类,访问修饰符子类不能小于父类(只取好的情况)
在重写方法中:子类的访问修饰符 跟父类的访问修饰符比较: 相同或大于
在重写方法中:子类的返回值类型 跟父类的返回值类型比较: 相同或是其子类
super关键字(重点)
super代表对当前对象的直接父类对象的引用
super可以调用直接父类的成员变量
(注意权限修饰符的影响,比如不能访问private成员)super可以调用直接父类的成员方法
(注意权限修饰符的影响,比如不能访问private成员)super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。
要想同时用this和super只能错开调用。
和this关键字的区别:
this是对象内部指代自身的引用
-
this可以调用成员变量,通常用于解决成员变量和局部变量同名冲突
-
this可以调用成员方法
-
this可以在构造方法中调用重载的构造方法,且必须是构造方法的第一条语句。
同一个类中的方法可以互相调用,this.可以省略不写。
继承状态下子类构造器的执行顺序(重点)
扩展:继承条件下,子类构造方法的执行过程:先找到最顶级父类,先执行顶级父类的构造方法,再向下执行一级父类构造,二级父类构造,直到当前子类构造
(如果父类有多个构造器,执行子类调用的构造)
子类一定会调用父类的构造器,没调用有参构造时,会默认调用父类的无参构造
Object类(要会重写equals、toString、hashCode)上面干货分享
包名:java.lang(程序自动导入)
Object是公有类
构造器是公有无参构造
Object类没有属性
11个方法:
重点掌握 | 反射时讲 | 线程时讲 | 垃圾回收机制 | 克隆(用不到了) | |
---|---|---|---|---|---|
equals() | getClass() | notify() | finalize() | clone() | |
hashCode() | notifyAll() | ||||
toString() | wait() | ||||
wait(long timeout) | |||||
wait(long timeout,int nano) |
注意:System.out.println(引用类型对象);<-等价于->System.out.println(引用类型对象.toString());
注意:重写equals()方法是因为调用时应该比较两个对象之间属性值是否相同,相同true,不同false
注意:一般情况下,重写equals()后,也要重写hashCode()方法
扩展:先判断两个对象的hashCode()值是否相同,hashCode值不同则认为是不同的对象,直接存储到集合里。当hashCode值相同时(因为hashCode有可能是多个数相加,所以值还是可能一致的)要再用equals方法进行比较,如果为true则是相同对象,不进行存储,否则为false进行存储
==和equals的区别和联系(重点)
==:
a) 基本类型,比较的是值
b) 引用类型,比较的是地址
c) 不能比较没有父子关系的两个对象
equals()
a) 系统类一般已经覆盖了equals(),比较的是内容。
b) 用户自定义类如果没有覆盖equals(),将调用父类的equals(比如是Object),而Object的equals的比较是地址(return (this == obj);)
c) 用户自定义类需要覆盖父类的equals()
注意:Object的==和equals比较的都是地址,作用相同
equals()比较String、Integer、Date的内容是否相同(比对象是地址,可重写比较对象)instanceof判断对象是不是这个类的实体