1. 面向对象的编程思想:
面向对象的编程思想就是把一个事物看成一个整体,把这个事物中的属性(特征)和功能(方法)表述出来。
面向对象的编程思想更贴近于人的正常思维方式。
面向对象的编程思想来源于生活服务于生活。
面向对象的编程思想中,一定会用到面向过程(以流程为基本单位,注重最后结果。)的编程思想。有缺陷:功之间有很强的关联。不利于程序的维护和扩展。
面向对象的特征:抽象!! 封装!! 继承!! 多态!! 。
2. 对象
在现实生活中,具体存在的一个事物。
在java编程中,万事万物皆对象。
特点:
在java编程中,无论两个事物多么相近或是相似,他们永远都是两个不同的对象。
各种法律、规则制度也是一种对象。
对象的内存图解 1
1.在堆内存中开辟一个空间并分配地址
2.按照类的描述,在该空间中定义成员变量 并且有默认初始化值
3.加载成员函数进入方法区(只加载一次)
4.对象创建完毕 将空间地址赋值给相应的变量
5.变量(p1/p2)调用成员变量
先通过该变量所存储的地址去堆空间中找
然后在该空间中找相应的成员变量
6.变量(p1/p2)调用成员函数
直接去方法区中找该成员函数
将该函数加载进栈内存开始运行
为了方便区分哪个对象调用的该成员函数
由this这个关键字段 来区分 this主要存的是当前对象的地址
注意:当成员函数在操作变量的时候
先在当前函数的空间里找 局部变量
如果没有找到,再去this所指向的堆内存中对象所属空间里去找
3. 抽象
在java编程中,抽象就是把同一个事物中,共同的属性(特征)和功能进行抽取、归纳、总结。
4. 封装
封装就是把抽取、归纳、总结的共同属性和功能进行包装,目的:保证抽取出来的数据的安全性。
封装就是包装的过程。
封装包括:
属性的封装
功能的封装
注意:封装不是绝对的封装,如果其他程序要访问已经封装好的数据,则需要通过程序指定的接口和方法才能获取。
java中属性的封装和方法的封装是密不可分的,相辅相成的。
面向对象三大特征:封装 继承 多态
封装:从字面意义上来看 封装就是将一些杂七杂八的东西进行统一的管理
收纳盒 衣柜 冰箱 书柜
最大的好处就是节约代码 方便管理 降低耦合性
在代码中有什么体现:
循环:主要解决有规律且重复性执行的代码
函数:主要解决具有独立功能的一段代码 后期进行复用即可
数组:主要解决多种同类型数据的操作 统一操作 方便类管理
类:主要将数据和行为进行统一方便操作 仿真现实中的事物
5, 类
java中类,是程序的核心。java程序中“万事万物皆对象!” 类是对象的模板和图纸!
类描述了对象的属性和功能,类是对象的模板,图纸。
对象是类的一个实例,是实实在在的个体。
对象是类的实体化,类是对象的抽象。
6, 方法
方法是实现某个功能的代码块。
方法的定义语法:
【访问修饰符】 void 方法名(){ }
说明:void就是表示该方法时无返回值的。
【访问修饰符】 void 方法名(){ }
无返回值无参数的普通方法。
【访问修饰符】 void 方法名 (数据类型 数据名){ }
无返回值的有参数的普通方法。
【访问修饰符】数据类型 方法名(){ return; }
有返回值有无参数的方法。说明:1返回值类型有返回值来决定。
在有返回值方法中,最后一句代码一定是return返回值。
【访问修饰符】返回值类型 方法名(参数列表){ return返回值; }
7变量
变量分类: 基本数据类型变量 和 引用数据类型变量。
位置划分: 局部变量 全局变量(成员变量)
1.存储位置
局部变量存储在栈内存中函数的所属空间里
成员变量存储在堆内存中对象的所属空间里
2.生命周期
局部变量随着函数的进栈而存在,随着函数的弹栈而消失
成员变量随着对象的创建而存在,随着对象的销毁而消失
3.访问范围
局部变量的访问范围仅仅在函数当中
成员变量的访问范围在当前类中
4.初始化值
局部变量必须先进行初始化 之后再能被调用
成员变量在创建时有默认初始化
局部变量: 位于方法中(构造方法 / 功能方法)中的变量。注意:局部变量一定要初始化才能使用。
全局变量: 位于类中,任何方法或代码块的外部。全局变量(成员变量)==全局属性(成员属性)。注意:任何全局属性都不能直接在慢方法中使用。main
成员属性如果没有初始化,jvm会根据属性的类型来制动初始化。
初始化默认值:应用类型:null。数值类型:int 0、double 0.0。char 小写a。Boolean类型 false。
8对象(创建对象)
new关键字是创建对象的标识符。创建对象就是构造方法创建出来的。
构造方法的定义:
a构造方法的方法名和类名相同。
b构造方法的没有void和没有有返回值。
c构造方法不能被static来修饰。
构造方法语法:
【访问修饰符】 类名(参数列表){ }
构造方法的作用:
1 创建对象
2 为成员属性初始化
调用成员属性:
对象名.属性名;
调用方法:
对象名.方法名(参数列表);
构造方法分类:
有参构造方法 (隐式和显示)
无参构造方法
无参的构造方法又叫默认的构造方法,它又分为隐式构造方、显示构造方法。注意:当一个类中如果没有任何自定义的构造方法,jvm会制动默认一个隐式的构造法,
当类中如果有了一个自定义的构造方法,那么那个默认的隐式构造方法jvm将不再提供。
【】如果一个类中,已经存在了一个有参数的构造方法,那么还想通过无参的构造方法来创建对象,可以再建一个无参的构造方法。
9. 多态
多态 就是指通一种事物在不同的情况下有多种表现形式。
多态 的两种表现形式:
方法重载
方法重写
方法重载:
在同一个类中,有多个方法名称相同,但是参数不同,这就是方法重载。
说明:参数列表的不同包括:数据类型不同、长度不同、顺序不同。
注意:普通方法和构造方法都可以重载;方法重载会根据传递参数来决定用哪个方法。
参数返回值不同,其他的都相同是够不成方法重载的。
10.方法中参数的传递
在java中无论是基本数据类型还是引用数据类型,在进行参数传递时,都是采用的值传递(也就是传递的都是具体的数据)。
基本数据类型:在进行参数传递时,传递的是值得副本(也就是说把当前数据复制了一份,然后再进行传递,所以目标方法中,
对参数进行修改,这个值得本身没有任何变化)。
引用数据类性:在进行参数传递时,传递的是数据所在的内存地址,所以 在目标方法中,对参数进行修改,这个值得本身也会
发生变化。
11.构造函数
2.我们只能将对象创建完毕之后,再进行对成员变量的赋值
对于一个人而言 是出生后才有的性别 还是出生前就有性别
有些人 出生前就有姓名了 有些人出生后才有的姓名
隐喻的对象
有些对象创建之前成员变量就有值(不含默认初始化)
有些对象创建之后成员变量才有值
所以就有一个问题了 如何在创建对象之前之中对我们的成员变量进行赋值呢?
构造函数的主要作用:在创建对象之时对成员变量进行赋值操作
构造函数的格式:
权限修饰符 函数名(参数列表){
函数体;
}
对比和之前学过的函数来说
构造函数
没有函数类型关键字
没有返回值类型(并不意味着没有return)
函数名必须是类名
但凡创建一个对象 构造函数就执行一次
问题:我们之前并没有写构造函数
如果类中没有定义任何构造函数的情况下,则会有一个默认无参的构造函数
public ClassName(){}
如果类中有明显定义的构造函数 则默认无参的构造函数不存在了
所以 一般而言 我们最好将那个无参的构造函数写出来!!!!!!!
成员变量的赋值其实经历了三个阶段
默认初始化- 显式初始化 - 针对性初始化
类中成员变量被赋值 构造函数
对象的内存图解 2
1.在堆内存中开辟一个空间并分配地址
2.对成员变量进行【默认初始化】
3.相应的构造函数进栈 刚开始就对成员变量进行【显式初始化】
4.接着再去执行构造函数中的内容【针对性初始化】
5.构造函数执行完毕 弹栈 将对象的地址赋值给相应变量即可
STACK
/**
Stack是一个简单的由一维数组实现的栈结构
支持入栈出栈等常见操作,但不支持动态扩容操作
为了方便简化代码,默认此Stack中只能存储int型数据
@author HENG
@version 1.0
*/
public class Stack{
private int[] data; // 容器 用于存储栈元素 data.length表示栈的最大容量
private int top=-1; // 栈顶标记 用于标记栈顶元素的位置 当栈为空时 top=-1 栈中有效元素的个数top+1
private int capacity=10; //默认最大容量为10
/**
创建一个默认容量为10的栈
*/
public Stack(){
this.data=new int[capacity];
}
/**
创建一个指定容量为capacity的栈
@param capacity 由调用者传入的指定容量
如果capacity<0 则容量置为0
如果capacity>100 则容量置为100
*/
public Stack(int capacity){
if(capacity<0){
capacity=0;
}
if(capacity>100){
capacity=100;
}
this.data=new int[capacity];
}
/**
将元素e入栈,如果栈当前已满,则无法加入
@param e 用户指定入栈的元素
*/
public void push(int e){
if(size()==data.length){
System.out.println(">>>栈已满,无法添加元素"+e);
return;
}
data[++top]=e;
}
/**
从栈中弹出一个元素,如果栈已经是空,则返回-1即可(没有学异常 -1表示错误)
@return 返回当前栈顶的元素,如果栈为空则返回-1
*/
public int pop(){
if(isEmpty()){
System.out.println(">>>栈为空,无法弹栈元素");
return -1;
}
return data[top--];
}
/**
获取当前栈顶元素(不出栈),如果栈已经是空,则返回-1即可
@return 返回当前栈顶的元素,如果栈为空则返回-1
*/
public int peek(){
if(isEmpty()){
System.out.println(">>>栈为空,无法获取栈顶元素");
return -1;
}
return data[top];
}
/**
判断当前栈是否为空
@return true表示栈空 否则栈不为空
*/
public boolean isEmpty(){
return top==-1;
}
/**
清空当前的栈
*/
public void clear(){
top=-1;
}
/**
获取栈中有效元素的个数
*/
public int size(){
return top+1;
}
/**
返回栈的字符串表现形式
*/
public String toString(){
if(isEmpty()){
return "[]";
}
String s="[";
for(int i=0;i<size();i++){
s+=data[i];
if(i==size()-1){
s+="]";
}else{
s+=",";
}
}
return s;
}
}
MYSTRING
/**
仿照Java自带的String类 写一个自己的MyString类,
基本支持String中大部分的功能。
其实String的本质就是一个一维的字符数组,然后再加上其相关的操作
数组的长度一旦确定 则不可更改;
String的长度一旦确定 也不可更改;
更重要的是,String的内容一旦确定 也不可更改;
String是一个不可变对象 意味着我们不能在原地修改String的内容 只能重新创建一份进行修改。
@author HENG
@version 1.0
*/
class MyString{
private char[] value;
/**
创建一个空串"",也就是说字符串长度为0
*/
public MyString(){
this.value=new char[0];
}
/**
创建一个由指定字符编码组成的字符串
*/
public MyString(byte[] bytes){
this.value=new char[bytes.length];
for(int i=0;i<value.length;i++){
value[i]=(char)bytes[i];
}
}
/**
创建一个由指定字符组成的字符串
*/
public MyString(char[] value){
this.value=new char[value.length];
for(int i=0;i<value.length;i++){
this.value[i]=value[i];
}
}
public char charAt(int index){
if(index<0||index>=value.length){
System.out.println(">>>角标越界"+index);
return (char)-1;
}
return value[index];
}
public int indexOf(int ch){
for(int i=0;i<value.length;i++){
if(value[i]==ch){
return i;
}
}
return -1;
}
public int length(){
return value.length;
}
//比较两个字符串之间的大小
//两个字符数组从左到右挨个比较元素 如果出现第一个不相等的元素 返回差值即可
//如果某一个数组遍历完了也没有发现不相等的 返回长度的差值即可
public int compareTo(MyString other){
int min=Math.min(length(),other.length());
for(int i=0;i<min;i++){
if(value[i]!=other.value[i]){
return value[i]-other.value[i];
}
}
return length()-other.length();
}
public boolean contains(MyString other){
char[] c1=value;
char[] c2=other.value;
if(c2.length>c1.length){
return false;
}
for(int i=0;i<c1.length;i++){
boolean flag=true;
for(int j=0;j<c2.length;j++){
if(c2[j]!=c1[i+j]){
flag=false;
break;
}
}
if(flag){
return true;
}
}
return false;
}
}
来源:CSDN
作者:稚于最初☜
链接:https://blog.csdn.net/qq_43199083/article/details/104677773