面向对象编程
Java的核心就是OOP
初始面向对象
- 面向过程思想:步骤思维清晰,第一步做什么,第二步做什么…。适合解决一些简单的问题
面向对象思想:物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行独立思考。最后,才对某个分类下的细节进行面向过程的思索。适合解决一些复杂的问题,适合处理需要多人协作的问题
对于描述复杂的事务,为了从宏观上把握,从整体上分析,我们需要使用面向对象的思路来分析整个系统,但是,具体到宏观操作,仍然需要面向过程的思路去处理
- 面向过程编程(OOP)
本质就是:以类的方式组织代码,以对象的形式(封装)数据
抽象
三大特性:
封装:将一些属性和相关方法封装在一个对象中,对外隐藏内部具体实现细节。内部实现,外界不需要关心,外界只需要根据”内部提供的接口“去使用就可以。
继承:个类”拥有“另外一个类的”资源“的方式之一;”拥有“:并不是资源的复制,编程双份资源,而是,资源的”使用权“;”资源“:指"非私有的"属性和方法
多态:一个类,所延伸的多种形态
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的。是对对象的抽象
从代码运行角度考虑是先有类后有对象。类是对象的模板
方法回顾和加深
- 方法的定义
修饰符
返回类型
//main方法
public static void main(String[] args) {
}
//定义方法
/*
修饰符 返回值类型 方法名(..){
//方法体
return 返回值;
}
*/
public String sayhello(){
return "hello,world!";
}
//void返回空值
public void hello(){
return;
}
public int max(int a,int b){
return a>b?a:b;
}
break和return的区别:前者跳出switch结束循环,后者代表方法结束,返回一个结果。return返回值必须与返回值类型相同
方法名:注意规范,见名知意
参数列表:(参数类型,参数名)…
异常抛出:
public void readFile(String file) throws IOException{
}
- 方法的调用:递归
静态方法与非静态方法
静态方法:static
非静态方法:
以下三种情况:
- 第一种情况:都是非静态方法,可直接调用
public void a(){
b();
return;
}
public void b(){
return;
}
- 第二种情况:都是静态方法,可直接调用
public static void a(){
b();
return;
}
public static void b(){
return;
}
- 第三种情况:
public static void a(){
b();
return;
}
public void b(){
return;
}
此处a有static,是和类一起加载的,时间片很早;b和对象有关,是类实例化之后才存在。已经存在的东西调用一个不存在的东西,不可行
形参和实参:
实际参数和形式参数类型要对应
public static void main(String[] args) {
int add = demo2.add(2, 3);
System.out.println(add);
}
public static int add(int a,int b){
return a+b;
}
值传递和引用传递:
- 值传递
//值传递
public class demo3 {
public static void main(String[] args) {
int a=1;
System.out.println(a);
demo3.change(a);//还是等于1,因为1只是传给了函数change的形式参数,函数并没有返回值
System.out.println(a);
}
public static void change(int a){
a=10;
}
}
输出:
1
1
- 引用传递
引用传递,传递的是一个对象
public class demo4 {
public static void main(String[] args) {
Student student=new Student();
System.out.println(student.name); //输出null
demo4.change(student);
System.out.println(student.name); //输出小张
}
public static void change(Student student){
//student是一个对象,指向的是Student student=new Student();,这是一个具体的人,可以改变属性
student.name="小张";
}
}
//定义一个student类,有一个属性name,这个类要怎么用呢
class Student {
String name;
}
this关键字:
后续出
类与对象的创建分析
类是一种抽象的数据类型,它是对某一事物整体描述/定义,但是并不能代表某一具体的事物。对象是抽象概念的具体实例
- 创建与初始化对象
使用new关键字创建对象的时候:
使用new关键字创建时,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
必须使用new关键字创建对象,构造器 Student xiaoming = new Student();
对象的属性 xiaoming.name
对象的方法 xiaoming.sleep()
类中的构造器也称构造方法,是在进行创建对象的时候必须要调用的。并且构造器要有以下两个特点:必须和类的名字相同;没有返回类型也不能写void
对象是通过引用来操作的:栈--------->堆
方法的定义与调用
一个项目应该只有一个main方法
创建类的时候:
类里面只能有属性(静态的属性)和方法(动态的行为)
举个例子:
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
//把抽象的Student类实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
Student xiaoming = new Student();
Student xiaohong = new Student();
System.out.println(xiaohong.name);
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
System.out.println(xiaohong.age);
}
}
输出:
null
null
0
0
package com.zxy.oop;
//学生类
public class Student {
//对象的属性
String name;
int age;
//对象的方法
public void study(){
System.out.println(this.name+"在学习");
}
}
属性默认的初始化:运行后输出null和0,说明String(引用数据类型)默认值为null,int默认值为0
扩展:基本数据类型:double默认值为0.0,char默认值为u000,boolean默认值为false,引用是null
在Application.java里加上
xiaoming.name="小明";
xiaohong.name="小红";
xiaoming.age=18;
xiaohong.age=19;
xiaohong.study();
xiaoming.study();
输出:
小红
小明
18
19
小红在学习
小明在学习
感慨:学程序是为了对世界更好的建模
- 构造器详解
- 系统自带的构造器
package com.zxy.oop;
public class GouZao {
public static void main(String[] args) {
}
}
这个类没有写任何东西,系统也会创造一个方法,即构造方法(构造器)
比如此例子构造器为:(可以去out文件夹下查看)
public GouZao() {
}
- 当然我们也可以显式的定义构造器:
先来个无参构造
package com.zxy.oop;
public class GouZao {
String name;
//实例化初始值
public GouZao(){ //无参构造
this.name="zxy";
}
}
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
//new实例化一个对象
GouZao gouZao = new GouZao();
System.out.println(gouZao.name);
}
}
输出:
zxy
使用new的时候,本质是在调用构造器
构造器用来初始化
加上有参构造(alt+insert),此时如果想使用无参构造,则必须显示地定义无参构造*
package com.zxy.oop;
public class GouZao {
String name;
//实例化初始值
public GouZao(){ //无参构造
}
public GouZao(String name){ //有参构造
//前面的代表对象本身的name,后面的那么代表实参传递下来的name
this.name=name;
}
}
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
//new实例化一个对象
GouZao gouZao = new GouZao("zhangxuanyu");
System.out.println(gouZao.name);
}
}
输出:
zhangxuanyu
此处用的有参构造不用无参构造是因为:
在Application
类的main
方法中,使用了new GouZao("zhangxuanyu")
来创建一个GouZao
对象。这行代码明确地传递了一个字符串参数"zhangxuanyu"
给构造函数。因此,Java会查找匹配这个调用的构造函数,即带有相同类型和数量参数的构造函数。
GouZao
类中定义了两个构造函数:
- 无参构造函数
public GouZao()
,它不接受任何参数。 - 带有一个
String
参数的构造函数public GouZao(String name)
。
当你执行new GouZao("zhangxuanyu")
时,Java会选择第二个构造函数,因为它与调用相匹配:它接受一个String
类型的参数,并将这个参数值赋给了实例变量name
。所以,gouZao.name
会被设置为"zhangxuanyu"
,并且当你打印它时,你会看到输出"zhangxuanyu"
。
如果你想要使用无参构造函数,可以这样做:
GouZao gouZao = new GouZao(); // 使用无参构造
在这种情况下,name
属性将不会被初始化(对于引用类型,默认值是null
),除非你在无参构造函数内部给它赋值。
选择使用哪个构造函数取决于你是否需要在对象创建时就初始化对象的状态。有参构造允许你直接在创建对象时提供必要的信息,使得对象可以处于一个有效的初始状态。而无参构造则通常用于不需要立即初始化或者需要默认初始化值的情况下。
- 创建对象内存分析
举个例子:
运行完Student.Pet dog = new Student.Pet();,内存为:
运行完:
dog.name="xiaozhang";
dog.age=14;
dog.shout();
面向对象三大特性
- 封装
该装的装,该露的露
- 程序设计追求”高内聚,低耦合“。前者指类的内部数据数据操作细节自己完成,不允许外部干涉;后者指仅暴露少量的方法给外部使用
数据的隐藏
- 通常,应禁止直接访问一个对象中数据的直接表示,而应通过操作接口来访问,这称为信息隐藏
属性私有(private),get/set
举个例子:
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
students s1 = new students();
s1.setName("zxy");
System.out.println(s1.getName());
}
}
package com.zxy.oop;
public class students {
//加private使得属性私有
private String name; //名字
private int id; //学号
private char sex; //性别
//提供一些可以操作这个属性的方法
//提供一些public的get,set方法
//get获得这个数据,set给这个属性设置值
public String getName(){
return this.name;
}
public void setName(String name){
this.name=name;
}
}
方法可以用alt+insert生成
不合法的数据可以通过封装避免
public void setAge(int age) {
if(age>120||age<0){
this.age=3; //不合法的数据
}else {
this.age=age;
}
}
作用:
提高程序安全性,保护数据
隐藏代码的实现细节
统一接口
系统可维护性
- 继承
- 什么是继承
继承的本质是对某一批类的抽象,从而实现对世界更好的建模
extends的意思是”扩展“。子类是父类的扩展
package com.zxy.oop;
//人(父类,基类)
public class Person {
public void say(){
System.out.println("说了一句话");
}
public int money=10_0000_0000;//注意!!,如果改成private私有,子类就没法用
}
可以创建:
package com.zxy.oop;
//学生 is 人(子类,派生类)
public class Student extends Person {
}
package com.zxy.oop;
//Teacher is 人
public class Teacher extends Person{
}
Java类中只有单继承,没有多继承.儿子只有一个爸爸,但是一爸爸可以有多个儿子
继承是类和类之间的关系。除此之外,类和类之间的关系还有依赖,组合,聚合等
继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,用关键字extends来表示
子类和父类之间,从意义上来说应该具有”is a“的关系
举个例子:
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.money);
}
}
输出:
说了一句话
1000000000
子类继承了父类,就会拥有父类的全部方法(public)
一般来说方法是公有的,属性是私有的
根据此再改进一下:
package com.zxy.oop;
//人
public class Person {//方法共有
public void say(){
System.out.println("说了一句话");
}
private int money=10_0000_0000;//属性私有
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
- object类
快捷键ctrl+H
右边的树形结构,Object是什么?
把Person.java清空,发现
new 的person很多方法,没定义过但存在。因为:
Java中所有的类都默认直接或间接继承Object类
- Super详解
- 发现可以在子类中用super调用的父类的属性
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("xiaohong");
}
}
输出:
xiaohong
xiaoming
zxy
package com.zxy.oop;
//学生 is 人:儿子
public class Student extends Person {
private String name="xiaoming";
public void test(String name){
System.out.println(name);//这个指定义函数的形参String name:xiaohong
System.out.println(this.name);//这个指上面的xiaoming
//调用父类的name:zxy
System.out.println(super.name);
}
}
package com.zxy.oop;
//人:父亲
public class Person {
protected String name="zxy";
}
- 也发现可以在子类中用super调用的父类的方法,比如:
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test1();
}
}
输出:
Student
Student
Person
package com.zxy.oop;
//学生 is 人:儿子
public class Student extends Person {
private String name="xiaoming";
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
}
package com.zxy.oop;
//人:父亲
public class Person {
//如果此print()是私有的,那么无法被继承
public void print(){
System.out.println("Person");
}
}
- 关于构造器
package com.zxy.oop;
public class Application {
public static void main(String[] args) {
Student student = new Student();
}
}
输出:
Person无参实现了
Student无参实现了
package com.zxy.oop;
//学生 is 人:儿子
public class Student extends Person {
private String name="xiaoming";
//隐藏代码:调用了父类的无参构造
//super();
public Student() {
System.out.println("Student无参实现了");
}
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
}
package com.zxy.oop;
//人:父亲
public class Person {
public Person() {
System.out.println("Person无参实现了");
}
//如果此print()是私有的,那么无法被继承
public void print(){
System.out.println("Person");
}
}
根据结果可推出Student.java里有隐藏代码(super()
标签:java,name,void,第五章,面向对象编程,Student,zxy,public,String From: https://blog.csdn.net/2301_80484013/article/details/145326166