对象:现实世界是由很多对象组成的,对象是真实存在的单个个体。
类:代表一类事物,个体。基于对象抽出了类。
类的属性:
- 静态:所有对象所共有的属性或特征,称之为成员变量(或数据成员)
- 动态:所有对象所共有的行为,称之为成员方法
二者关系:类是对象的模板,对象是类的具体实例。
如下:
类(数据类型) 引用(引用类型变量) 对象
Student stu = new Student();
(引用类型默认为null)
方法签名:方法名+参数列表
方法的重载(Overload):方法的签名不同,其中方法签名中的方法名称相同,参数列表不同,编译器在编译时会根据方法的签名自动绑定调用的方法。
public void love(){
...
}
public void love(String str){
...
}
public int love(int love){
...
return love;
}
以上实现了对方法love的重载,使用时根据具体的参数列表进行调用。
构造方法:
- 与类同名,没有返回值
- 常常用于给成员变量赋初始值
- 在创建(new)对象时被自动调用
- 在类中,如果不写构造方法,编译器会默认一个无参的构造方法;如果写了,编译器则不默认提供无参构造方法。
- 构造方法可以进行重载
类名:Student
this:指代当前对象,只能用在方法中,方法中访问成员变量之前默认有个(this.)
null:空,没有指向任何对象。如果引用的值为空,则不能对该引用执行任何操作,
否则,操作的话,会发生空指针异常(NullPointerException)
String stu;
public Student(String str){
this.stu=str;//this可以自己写(一般用于成员变量和参数变量同名时),也可以不写。不写时由编译器默认提供,并不是不存在
}
“=”在引用之间的使用
- 指向同一个对象
- 通过一个引用对数据的修改,会影响另一个引用对数据的访问
public class Student {
private Integer age;
private String message;
public Student(Integer age, String message) {
super();
this.age = age;
this.message = message;
}
public void setAge(Integer age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "Student [age=" + age + ", message=" + message + "]";
}
public static void main(String[] args) {
Student stu=new Student(21,"我很帅");
Student stu2=stu;
System.out.println("未对其中之一的信息进行修改--stu:"+stu+",stu2:"+stu2);
//未对其中之一的信息进行修改--stu:Student [age=21, message=我很帅],stu2:Student [age=21, message=我很帅]
stu.setAge(18);
stu.setMessage("我很可爱");
System.out.println("对其中之一的信息进行了修改--stu:"+stu+",stu2"+stu2);
//对stu的数据执行修改,stu2的访问数据也发生了相应的变化
//对其中之一的信息进行了修改--stu:Student [age=18, message=我很可爱],stu2Student [age=18, message=我很可爱]
}
}
“=”在基本变量之间的使用
- 赋值
- 对一个变量的修改不会影响另一个变量的值
面向对象的三大特性:
封装:对具有特定功能的方法/类进行代码封装,实现对局部功能的代码复用
继承:java中的继承遵循单继承原则
- 通过extends来实现继承
- 主要可实现代码的复用
- 超类:所有派生类所共有的属性和行为;派生类:派生类所特有的属性和行为
- 派生类继承超类后,派生类具有超类的和派生类的属性和行为(单一继承,超类可以有多个派生类,而派生类只能有一个超类)
- 继承具有传递性
- 构造派生类之前必须先构造超类(注意:在派生类的构造方法中若没有调用超类的构造方法,则默认super()调用超类的构造方法;在派生类的构造方法中若调用了超类的构造方法,则不再默认提供;super()调用超类的构造方法,必须位于派生类构造方法的第一句)
super:指代当前对象的超类对象
public class People{
public People(){
...
}
public People(String str){
...
}
}
public class Student extends People{
public Student(){
super();//必须位于第一句,如果父类中写了有参构造函数,则父类中编译
//器不会提供默认的无参构造;当子类调用父类中的构造时,调用默认的父类构造会报错
//此时调用父类构造方法时要根据父类已经书写的构造方法进行书写调用
...
}
public Student(String str){
super(str)//必须位于第一句,写了就不会默认提供无参构造
...
}
}
3.多态:不同的表现形式
- 不同类型的引用指向不同的对象时,有不同的实现–行为的多态
- 同一对象被造型为不同的类型时,有不同的功能–对象的多态
向上造型:超类型的引用指向派生类的引用(能调用出来什么看引用的类型)
类People 方法有:love
类Student 方法有:like
类Student继承了类People
向上造型:
People p=new Student();
p.love();//引用P只能调用出People的方法,--love
注意:如果父类中的该方法被子类重写,则该引用调用的是子类中重写方法
自动类型转换/强制类型转换
- 超类型的引用指向派生类的对象–自动类型转换(小类型转换为大类型为自动转换[能转换的类型为:继承的超类+实现的接口])
- 强制类型转换(大转小)–能成功的条件为:引用所指向的对象就是该类型;引用所指向的对象继承了该类或者实现了该接口
类A
类B 继承了A,实现了D
类C 实现了D
接口D
A a=new B();
B b=(B)a;//转换成功,--引用所指向的对象就是该类型
C c=(C)a;//失败 引用所指向的对象与该类型没有任何关系
A a2=(A)a;//转换成功,--引用所指向的对象继承了该类
D d=(D)a;//转换成功,--引用所指向的对象实现了该接口
如果引用类型需要进行强制转换的时候,一般先进行一次判断,成功则转换。
if(a[需要强转的引用] instanceof B[强转的类型]){
B b=(B)a;
}
System.out.println(a instanceof B); //true
System.out.println(a instanceof D); //true
System.out.println(a instanceof C); //false
方法的重写(Override):对父类中的方法进行覆盖,重写方法体
-
方法的重写发生在父子类中,方法的签名相同,方法体不同
-
重写的方法被调用的时候,看对象的类型
-
重写遵循“两同两小一大”原则:
- 两同:方法名称相同,参数列表相同
- 两小:派生类方法的返回类型要小于或等于超类方法的返回类型(注意:返回值为基本类型的时候必须等于;返回值类型为引用类型的时候小于或者等于);派生类方法抛出的异常小于或者等于超类方法的
- 一大:派生类方法的访问权限大于或等于超类方法的
抽象方法:由abstract修饰,只有方法的定义,没有方法的具体实现
抽象类:由abstract修饰
- 包含抽象方法的类必须是抽象类,不包含抽象方法的类也可以定义为抽象类
- 抽象类是不能被实例化的
- 抽象类都是需要被继承的(由于不能被实例化,只有被继承才有意义,因为子类可以进行实例化)
- 抽象类可以封装派生类所共有的属性和行为(提高代码复用);可以为所有派生类提供统一的入口(派生类的具体的实现不同,入口一致);可以为所有的派生类提供统一的类型(向上造型)
接口:
- 是一种数据类型(引用类型)
- 由interface定义
- 只能包含常量和抽象方法
- 接口不能被实例化
- 接口是需要被实现的/(实现类必须重写接口中的所有抽象方法)
- 一个类可以重写多个接口,有逗号分隔(是继承的单根性扩展。若又继承又实现,应该遵循先继承后实现)
- 接口可以继承接口(同类型为继承,不同类型为实现)
注:文章全部内容是作者的学习经验总结,如果有不完美的地方,还请联系编者修改,亦或是你的疑惑编者在此处并未涉及到,也可以联系编者进行解答,完善。在此也欢迎更多的你加入我们。
加入我们,或是帮助我们改进,请扫: