Java编程基础阶段笔记 day 07 面向对象编程(上)

简介: 面向对象编程笔记Notes:面向对象三条学习主线、面向过程 VS 面向对象、类和对象、创建对象例子、面向对象的内存分析

  • 面向对象编程

笔记Notes

面向对象三条学习主线

面向过程 VS 面向对象

类和对象

创建对象例子

面向对象的内存分析

类的属性:成员变量

成员变量 VS 局部变量

类的方法

方法的重载

可变个数形参

面向对象:封装性

访问权限修饰符

构造方法(构造器)

给属性赋值的方法

UML类图

this 关键字


面向对象学习主线

类及类的成员:属性,方法,构造器,代码块,内部类

面向对象的三大特性:封装性,继承性,多态性

其他关键字:this,super,interface,final,static......

面向过程 vs 面向对象

面向过程:强调的是功能行为

面向对象 :强调具备了功能的对象

类和对象的区别

类:抽象的(汽车设计模板)

对象:具体的,类的实例(根据模板造出的汽车)

类的成员:属性和方法

属性 = field = 成员变量

(成员)方法 = 函数 = method

面向对象的例子

1.创建一个类,并在类中提供必要的属性和方法

2.由类派生出对象。(创建对象)

3.调用对象中的属性和方法。(对象名.属性名/方法名)

         //创建一个类

class Person{

      //属性

      String name;

      int age;

      char sex;

      

      //方法

      public void run(){

               System.out.println(name + "跑起来");

      }

      

      public void say(){

               System.out.println(name + "今年" + age);

      }

}

// main 方法中

               Person person = new Person();

               //调用属性 :对象名.属性名

               person.name = "王庆港"; //给属性赋值

               person.age = 23;

               //获取属性的值

               String name = person.name;

               System.out.println("name=" + name);

               //调用方法 :对象名.方法名

               person.run();

               person.say();

面向对象的内存分析

同一个类创建的多个对象,每个对象独自拥有一份属性。

当修改其中一个对象的属性的值后,其它对象的该属性不会受到影响

类的成员之 :属性(成员变量)

变量的分类:

①按照数据类型分 :基本数据类型 vs 引用数据类型

②按照位置分 :成员变量 vs 局部变量

成员变量和局部变量 相同点:

①变量的声明的格式都是一样的。

②变量都有作用域

③变量都是先声明后使用

成员变量和局部变量 不同点:

①局部变量:在方法里,方法的形参,构造器中,构造器的形参,代码块

②成员变量: 在类中方法等结构外

权限修饰符:

①局部变量:不能使用权限修饰符修饰

②成员变量:可以使用四种权限修饰符(public protected 缺省的(default) private)

内存:

①局部变量:在内存的栈中

②成员变量:在内存的堆(对象)中

默认值:

①局部变量 :没有默认值

②成员变量 :有默认值(和数组元素的默认值是一样的)

byte,short,int,long -> 0

float,double -> 0.0

boolean -> false

char -> u0000

引用数据类型 -> null

class Animal{

      //属性(成员变量)

      public String name = "动物";

      int legs;

      protected boolean isLive = true;

      {//代码块

               String address = "";//局部变量

      }

      public Animal(){} 

      //构造器

      public Animal(int sex){//构造器的形参

               int a = 10;//局部变量

      }

      //方法

      public void say(int sex){//方法的形参

               //局部变量

               int age = 10;

               age = 20;

               name = "大锤";

      }

}

不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。

如:new Person().shout();

类的成员:方法(method)

Java里的方法不能独立存在,所有的方法必须定义在类里。

方法的声明格式:

修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){

方法体程序代码

return 返回值;

}

权限修饰符 :public protected 缺省的 private (先用public)

①void/具体的类型(基本数据类型、引用数据类型):

②void : 表示该方法没有返回值

具体的类型 :调用该方法会有返回值。

注意:返回数据需要使用return关键字。return 后面跟需要返回的数据。

方法名 :只需要遵守标识符的规则和规范即可

(形参相同的情况下,同一个类中的方法名不能相同)。

形参列表 :可以有0个1个或多个。多个之间使用","隔开。

①作用 :用来通知方法的调用者调用此方法时需要传递数据。

②注意:实参的类型必须和形参的类型保持一致

方法体 :方法功能的具体体现。

注意 :只有调用方法时方法体才会执行。

对象数组题目:

定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。

问题一:打印出3年级(state值为3)的学生信息。

问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息

提示:

1) 生成随机数:Math.random(),返回值类型double;

2) 四舍五入取整:Math.round(double d),返回值类型long。

class Student1{

      int  number;

      int state;

      int score;

      

      @Override

      public String toString() {

               return "Student1 [number=" + number + ", state=" + state + ", score=" + score + "]";

      }

      

}

public class StuInfo {

      public static void main(String[] args) {

               // 创建对象数组

               Student1[] studentArr = new Student1[20];

               // 循环创建对象并赋值,传给对象

               

               for (int i = 0; i < 20; i++) {

                         Student1 student1 = new Student1();

                         student1.number = i;

                         student1.state = (int)Math.round( (Math.random()*7));

                         student1.score = (int) (Math.random()*100);   

                         studentArr[i] = student1;

               }

               System.out.println("---------打印排序前的学生信息-------------");

               for (int i = 0; i < studentArr.length; i++) {

                         System.out.println(studentArr[i]);

               }

               

               System.out.println("----------打印state为3的学生信息---------");

               // 循环查找对象数组中state值为3的对象,打印输出对象信息

               for (int i = 0; i < studentArr.length; i++) {

                         if (studentArr[i].state == 3) {

                                  System.out.println(studentArr[i]);

                         }

               }

               System.out.println("----------------------------------------");

               // 使用冒泡排序按学生成绩排序,并遍历所有学生信息

               // 思路:两个循环遍历数组中的对象的成绩,若对象的成绩小于后一个,则交换对象的位置

               for (int i = 0; i < studentArr.length -1; i++) { // 外层循环决定冒泡排序的次数,为数组长度-1

                         for (int j = 0; j < studentArr.length - i -1; j++) { // 内层循环决定每次多少次冒泡,为

                                  if (studentArr[j].score > studentArr[j+1].score) { // 如果前面的对象小于大于后面的,就叫交换类数组地址

                                            Student1 temp = studentArr[j];

                                            studentArr[j] = studentArr[j+1];

                                            studentArr[j+1] = temp;

                                  }

                         }

               }

               // 注意!!!!!!!!!!

               // 冒泡排序交换的值的数组的下标为内循环的循环变量

               System.out.println("------打印排序后的信息-------");

               // 打印排序后的信息

               for (int i = 0; i < studentArr.length; i++) {

                         System.out.println(studentArr[i]);

                                  

               }

               

      }

}

重载的概念、特点、实例

①在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。

②与返回值类型无关,只看参数列表,且参数列表必须不同。

(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。

③示例:

//返回两个整数的和

int add(int x,int y){return x+y;}

//返回三个整数的和

int add(int x,int y,int z){return x+y+z;}

//返回两个小数的和

double add(double x,double y){return x+y;}

注意!!:

①不同的形参列表 :形参的个数,顺序,类型不同

②方法的重载和权限修饰符,返回值类型,形参的名字无关。

③判断方法:只看 方法名 + 形参列表(看形参和实参的类型)

可变个数形参

格式 :变量的类型 ... 变量名

说明:

             ①可变形参的底层就是一个数组

             ②在可变形参的方法中,和可变形参相同类型的数组的方法不构成重载。

             ③在形参列表中可变形参只能放在最后

             ④在同一个方法的形参列表中只能有一个可变形参。

             ⑤ 可变形参的个数可以是0个1个或多个

方法的参数传递

基本数据类型的参数传递

引用数据类型的参数传递

方法的参数传递

面向对象:封装

为什么要使用封装性?

在创建对象以后,就可以通过对象名.属性名这种方式对属性直接进行操作。这种操作对于属性只有类型和范围的限制。但是在实际开发中我们会有更多的其它的限制条件。而这些限制条件又不能在属性的声明处加以限制。我们采取取如下方式

①使用权限修饰符对属性进行权限的限制,那么在类的外部就不能随意的再调用类中的属性

②提供公共的方法,在方法中可以加以限制其它的条件。然后可以通过该方法给属性赋值和获取属性的值。

封装性的体现(狭义上):

①将属性私有化。(private修饰属性)

②提供公共的set/get方法。(set方法用来给属性赋值,get方法用来获取属性的值)

封装性的体现(广义上):

①可以使用四种权限修饰符:private,缺省的,protected,public

②四种权限修饰符可以修饰 :属性,方法,构造器,内部类

③类只能被public和缺省的修饰。

四种访问权限修饰符

构造方法(构造器)

构造器的特征

它具有与类相同的名称

它不声明返回值类型。(与声明为void不同)

不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值

构造器的作用:创建对象;给对象进行初始化

如:Order o = new Order(); Person p = new Person(“Peter”,15);

根据参数不同,构造器可以分为如下两类:

隐式无参构造器(系统默认提供)

显式定义一个或多个构造器(无参、有参)

注 意:

Java语言中,每个类都至少有一个构造器

默认构造器的修饰符与所属类的修饰符一致

一旦显式定义了构造器,则系统不再提供默认构造器

一个类可以创建多个重载的构造器

父类的构造器不可被子类继承

构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。

给属性赋值的方法

赋值的位置:

① 默认初始化:int a;

② 显式初始化:int a = 0;

③ 构造器中初始化

④ 通过“对象.属性“或“对象.方法”的方式赋值

赋值的先后顺序:

① - ② - ③ - ④

JavaBean:Java语言编写的可重用组件

定义:是一个普通的Java类,但是符合如下标准

①类是公共的

②有一个无参的公共的构造器

③有属性,且有对应的get、set方法

UML类图

①+ 表示 public 类型, - 表示 private 类型,#表示protected类型

②方法的写法:方法的类型(+、-) 方法名(参数名:参数类型):返回值类型

this 关键字

this 是什么?

①它在方法内部使用,即这个方法所属对象的引用;

②它在构造器内部使用,表示该构造器正在初始化的对象。

this作用域:this 可以调用类的属性、方法和构造器

适用情形:当在方法内需要用到调用该方法的对象时,就用this。

具体的:我们可以用this来区分属性和局部变量。

public void setAge(int age){

       age = age;//局部变量 :就近原则(属性名和局部变量名相同时默认调用的是局部变量)

       System.out.println("===========" + age);

}

this 调用构造器

总结Summary

面向对象的内存分析

成员变量与局部变量

构造器

函数重载

目录
相关文章
|
8天前
|
Java
Java基础—笔记—static篇
`static`关键字用于声明静态变量和方法,在类加载时初始化,只有一份共享内存。静态变量可通过类名或对象访问,但推荐使用类名。静态方法无`this`,不能访问实例成员,常用于工具类。静态代码块在类加载时执行一次,用于初始化静态成员。
10 0
|
8天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
14 0
|
10天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第9天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析Java中的同步机制,包括synchronized关键字、Lock接口以及并发集合等,并探讨它们如何影响程序的性能。此外,我们还将讨论Java内存模型,以及它如何影响并发程序的行为。最后,我们将提供一些实用的并发编程技巧和最佳实践,帮助开发者编写出既线程安全又高效的Java程序。
22 3
|
13天前
|
设计模式 安全 Java
Java并发编程实战:使用synchronized关键字实现线程安全
【4月更文挑战第6天】Java中的`synchronized`关键字用于处理多线程并发,确保共享资源的线程安全。它可以修饰方法或代码块,实现互斥访问。当用于方法时,锁定对象实例或类对象;用于代码块时,锁定指定对象。过度使用可能导致性能问题,应注意避免锁持有时间过长、死锁,并考虑使用`java.util.concurrent`包中的高级工具。正确理解和使用`synchronized`是编写线程安全程序的关键。
|
11天前
|
Java
Java 并发编程:深入理解线程池
【4月更文挑战第8天】本文将深入探讨 Java 中的线程池技术,包括其工作原理、优势以及如何使用。线程池是 Java 并发编程的重要工具,它可以有效地管理和控制线程的执行,提高系统性能。通过本文的学习,读者将对线程池有更深入的理解,并能在实际开发中灵活运用。
|
7天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第11天】 在Java中,高效的并发编程是提升应用性能和响应能力的关键。本文将探讨Java并发的核心概念,包括线程安全、锁机制、线程池以及并发集合等,同时提供实用的编程技巧和最佳实践,帮助开发者在保证线程安全的前提下,优化程序性能。我们将通过分析常见的并发问题,如竞态条件、死锁,以及如何利用现代Java并发工具来避免这些问题,从而构建更加健壮和高效的多线程应用程序。
|
12天前
|
Java
Java并发编程:深入理解线程池
【4月更文挑战第7天】在现代软件开发中,多线程编程已经成为一种不可或缺的技术。为了提高程序性能和资源利用率,Java提供了线程池这一强大工具。本文将深入探讨Java线程池的原理、使用方法以及如何根据实际需求定制线程池,帮助读者更好地理解和应用线程池技术。
15 0
|
13天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
【4月更文挑战第6天】Java内存模型(JMM)是多线程编程的关键,定义了线程间共享变量读写的规则,确保数据一致性和可见性。主要包括原子性、可见性和有序性三大特性。Happens-Before原则规定操作顺序,内存屏障和锁则保障这些原则的实施。理解JMM和相关机制对于编写线程安全、高性能的Java并发程序至关重要。
|
3天前
|
设计模式 运维 安全
深入理解Java并发编程:线程安全与性能优化
【4月更文挑战第15天】在Java开发中,多线程编程是提升应用程序性能和响应能力的关键手段。然而,它伴随着诸多挑战,尤其是在保证线程安全的同时如何避免性能瓶颈。本文将探讨Java并发编程的核心概念,包括同步机制、锁优化、线程池使用以及并发集合等,旨在为开发者提供实用的线程安全策略和性能优化技巧。通过实例分析和最佳实践的分享,我们的目标是帮助读者构建既高效又可靠的多线程应用。
|
4天前
|
SQL 安全 Java
Java安全编程:防范网络攻击与漏洞
【4月更文挑战第15天】本文强调了Java安全编程的重要性,包括提高系统安全性、降低维护成本和提升用户体验。针对网络攻击和漏洞,提出了防范措施:使用PreparedStatement防SQL注入,过滤和转义用户输入抵御XSS攻击,添加令牌对抗CSRF,限制文件上传类型和大小以防止恶意文件,避免原生序列化并确保数据完整性。及时更新和修复漏洞是关键。程序员应遵循安全编程规范,保障系统安全。