JAVA学习-对象
面向对象
方法的补充
静态方法
static 可以直接调用。如果在不同的类只需要 类名.方法名 调用即可
//假如在pubilc class Studen 有个方法 public static void say (){...}
//需要在public class Other 的main方法里面调用
//只要在main方法里写:
Studen.say();//这样就完成调用了
静态方法是与类一起存在的
非静态方法
非静态方法的调用:
//假如在pubilc class Studen 有个方法 public void say (){...}
//需要在public class Other 的main方法里面调用
//只要在main方法里写:
//对象类 对象名 = 对象值
Student student = new Student();//实例化这个类 new
student.say;
非静态方法是要实例化后才存在的
抽象类的实例化
这是一个抽象类:
package com.oop.demo01;
//抽象类
public class Student {
//属性
String name;
int age;
}
他的实例化:
package com.oop.demo01;
public class Appliction {
public static void main(String[] args) {
//把类实例化
Student xm = new Student();
Student xh = new Student();
xm.name = "小明";
xh.name = "小红";
xm.age = 18;
xh.age = 16;
System.out.print(xm.name+"今年"+xm.age+"岁了\n");
System.out.print(xh.name+"今年"+xh.age+"岁了");
}
}
构造器
一个类其实什么都不写,它也会存在一个方法,也就是构造器。
构造器的方法名必须与类名完全相同。
构造器没有返回值。
无参构造器
显示的定义构造器如下:
public class Person {
public Person (){} //这是构造器
}
使用new关键字本质实在调用构造器!
而构造器的作用就是实例化初始值,构造器为空,所以实例化的初始值为null或0
构造器里面可以初始化属性,如下
public class Person {
String name;
int age;
String habit;
public Person (){
this.name = "tangxiaoyuan";
}
}
在main方法里输出如下:
public class Appliction {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);
System.out.println(person.age);
System.out.println(person.habit);
}
}
得到的结果如下图:
有参构造器
一旦定义有参构造,如果想使用无参构造,无参就必须显示定义
如下:
public class Person {
String name;
int age;
String habit;
public Person (){} //显示无参构造
public Person(int age,String name,String habit){
this.name = name; //this.name是属性 name是方法中定义形式参数用于传输
this.age =age;
this.habit = habit;
}
}
main方法输出如下:
public class Appliction {
public static void main(String[] args) {
Person person = new Person(18,"小红","跑步");
System.out.println(person.name);
System.out.println(person.age);
System.out.println(person.habit);
}
}
结果如下:
快捷键
Alt + Inset 自动生成构造器
注意
启动程序 Application 如果和需要使用的类在同一个包,属性前可以不用加public。如果不在一个包,属性必须要加public才能调用这个属性
如下:
package com.oop.demo01; //注意看这里
//抽象类
public class Student {
//属性
public String name; //加上public,包外面的才能调用
public int age;
public Student() {}
}
////////////////////////////
package com.oop; //注意看这里
import com.oop.demo01.Person; //注意这里
import com.oop.demo01.Student; //注意这里
public class Application {
public static void main(String[] args) {
Person person = new Person(18,"小红","跑步");
System.out.println(person.name);
System.out.println(person.age);
System.out.println(person.habit);
Student xm = new Student();
xm.age = 15;
System.out.println(xm.age);
}
}
创建对象内存分析
在程序运行Application时,走到Pet,如果堆里面的方法区没有Pet,则会创建一个Pet,Pet里面包含属性方法等。程序执行new时,会创建一个引用变量名,图中为dog和cat,代码如下:
Pet cat = new Pet;
Pet dog = new Pet;
此时,堆里会生成一个空间,存放cat和dog相关的内容,这个空间也就是抽象类实例化产生出来的实例,栈里面的引用变量名用来指向实例。注意:cat和dog虽然它们的抽象类都是Pet但是它们实例化地址并不相同。
封装
- 提高程序安全性,保护数据。
- 隐藏代码实现细节
- 统一接口
- 系统可维护增加了
属性私有:private
属性私有后外部不能使用。
get/set实现调用和修改。
代码如下:
package com.oop.demo02;
public class Student {
private int age; //私有数据
private String name;
private int num;
private char sex;
public void setAge(int age) { //实现给私有数据赋值
this.age = age;
}
public int getAge() {
return age;
}
}
///////////////////////////////////
package com.oop;
import com.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student xh = new Student();
xh.setAge(18);
System.out.println(xh.getAge());
}
}
继承
继承是类和类之间的关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
继承关系的两个类,一个为子类,一个为父类。子类继承父类,使用关键字extends来表示。
子类继承了父类,就会拥有父类的全部。(但不能继承私有的)
快捷键 Ctrl+H 打开继承树
在Java中,所有的类都默认直接或间接继承object类
一个儿子只能有一个爸爸,但一个爸爸可以有多个儿子
子类默认调用父类的无参构造,如下:
package com.oop.demo02;
public class Person {
public Person(){
System.out.println("Person无参启动了");
}
}
//////////////////////////////////
package com.oop.demo02;
public class Student extends Person {
public Student(){
System.out.println("Student 无参构造启动了");
}
}
////////////////////////////////////
package com.oop;
import com.oop.demo02.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
如果父类不显示无参构造,直接写有参构造,子类必须写有参构造,不然会报错调用父类无参构造。所以父类写有参构造一定要显示无参构造。
super
- super 调用父类的构造方法,必须放在构造方法的第一个。
- super必须只能出现在子类的方法或构造方法中
- super和this不能同事调用构造方法
super与this的区别
代表对象的不同:
this:本身调用者这个对象
super:代表父类对象的引用
使用的前提:
this:没有继承也可以使用
super:只能在继承条件下才可以使用
构造方法:
this() :本类的构造
super(): 父类的构造
重写
重写需要有继承关系,子类重写父类的方法
- 方法名必须相同
- 参数列表必须相同
- 修饰符:范围可以扩大但不能缩小: public > protected > default>private
- 抛出的异常:范围,可以被缩小,但不能扩大: ClassNotFoundException --> Excepetion(大)
重写,子类的方法和父类必须一致,方法体不同!
为什么要重写:父类的功能,子类不一定需要,或则不一定满足。
Alt + Insert : override
多态
多态注意事项:
- 多态是方法的多态,属性没有多态
- 父类和子类,有联系
- 存在条件:继承关系,方法需要重写,父类引用指向子类对象
Person s1 = new Student();
Student s2 = new Student();
上述代码中,s1,s2能执行的方法,主要看左边的类型,与右边关系不大。如下:
s1.run();
s2.run();
s2.son();
s1和s2都能执行run方法,因为子类父类都有run方法,但s1没有son方法,所以不能写s1.son
我们用重写,改s2中的也就是子类的run方法,因为 Person s1 = new Student(); 所以s1.run(); 会输出子类重写的内容
instanceof
instanceof的理解:
import com.oop.demo04.Person;
import com.oop.demo04.Student;
import com.oop.demo04.Teacher;
public class Application {
public static void main(String[] args) {
//Object > Person > Student
//Object > Person > Teacher
//引用类型 名称 实例
Object student = new Student();
System.out.println(student instanceof Student);//true
System.out.println(student instanceof Person);//true
System.out.println(student instanceof Object);//true
System.out.println(student instanceof Teacher);//false
/* 理解 instanceof 是判断x与y的关系(x在前,y在后)
instanceof 判断的结果与实例有关 student的实例为Student 所以它与Tecaher不是父子关系
但如果student的引用类型也与Teacher没有关系,那么student是无法与Tecaher用instanceof的
*/
}
}
类型转换
类型转换,有父类到子类,是强制转换
子类到父类,是自然转换
自然 转换过程,可能会丢失子类自己的方法。
子类型无法指向父类型的实例
思考如下:
import com.oop.demo04.Person;
import com.oop.demo04.Student;
public class Application {
public static void main(String[] args) {
Person person = new Student();
Student student = (Student) person;
}
}
/* 父类引用类型指向子类实例 然后将父类强制转换为子类 这个时候就是子类引用类型指向子类实例 没有问题
import com.oop.demo04.Person;
import com.oop.demo04.Student;
public class Application {
public static void main(String[] args) {
Person person = new Person();
((Student)person).go();
}
}
/* 这样强制转换会报错,因为person是父类引用指向父类实例,现在强制转换,就是让
子类引用指向父类实例。子类引用是不能指向父类实例的,这个很关键。
*/
所以强制转换的条件,一定得是强制转换的子类不能低于实例。
抽象类
接口
interface 接口中所有定义其实都是抽象的 public abstract
interface接口中所有定义的属性都是常量 public final
类可以实现接口 通过 implement 接口
实现了接口的类,就需要重写接口中的方法
内部类
内部类可以获得外部类的私有属性
如:
public class Outer {
private int id =202;
public class Inter{
public void In(){
System.out.println("这是内部类");
}
public void GetID(){
System.out.println(id);
}
}
}
/////////////////////////////////
import com.oop.demo05.Outer;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inter inter = outer.new Inter();
inter.GetID();
}
}
异常
异常处理五个关键字
try catch finally throw throws
public class Demo02 {
public static void main(String[] args) {
int a =1;
int b =0;
int c ;
try {
c = a / b ;
}catch (Exception e){
System.out.println("出现异常");
}finally {
c = 0 ;
}
System.out.println(c);
System.out.println("程序没有结束");
}
}
try catch finally 是捕获一个代码块的异常
throw是主动抛出异常,一般用在方法中
throws 在方法上抛出异常
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)