文章目录
面向对象基本概念(二)
数据表和简单java类的映射
设计各个类可以像数据库的数据表一样灵活的相互引用
对象的比较方式
不能直接用==
要实现内部所有属性的比较
String.equals()也是属性比较方法
属性比较方法应该在本类中完成
比如在类成员函数中实现.equals()或者.compare()这样的方法
封装属性,如被声明成private的属性可以通过内部方法引用传递访问
-
先进行地址判断,即本对象判断,比较栈空间地址,这样节省时间
-
为了防止NullPointerException的产生应该增加一个null判断
-
对象的属性也要进行地址数值判断,即使用==,这样如果效率更高
在本例中频繁大量的使用了this来指代当前对象.
static关键字
static关键字可以用来定义属性和方法
static定义属性
如果想把某个属性声明成公共属性可以在声明前加上static关键字
成为公共属性后,任何一个对象修改了此属性都会影响到其他对象
java中的四块常用内存区域
-
栈空间区域: 保存所有对象的名称, 即堆内存空间的地址
-
堆内存空间: 保存对象具体属性内容
-
全局数据区: 保存static类型属性
-
全局代码区: 保存所有方法定义
使用所有对象的公共代表来进行访问, 即使用类进行访问, 而不是单独实例化的对象进行访问
static对象可以由类名直接访问
所有非static对象都只能被实例化对象访问
一般描述共享性的属性, 不受实例化对象限制的属性时才会用static, 使用机会不是很高
static定义方法
定义static方法,可以用在类没有实例化对象的时候直接被调用,而不作为具体对象的成员使用
如果想定义类中的普通对象可以用static进行定义
static定义的属性和方法不受实例化对象的控制
static方法不能直接访问非static属性或方法,只能调用static属性和方法
非static方法可以访问static的属性和方法,不受任何限制
所有非static定义的结构碧素霞类明确实例化对象才会分配堆空间,之后允许被使用
static定义的结构不受实例化对象控制,可以随时访问
tips:
如果一个方法定义在主类中,并由方法中,使用public static进行声明(因为主方法也是个static方法)
如果定义在类内使用public
使用static的场景:
当类中没有属性产生,类中的方法全部用static声明
主方法
public: 对任何操作都是可见的
static: 证明此方法由类名称调用
void: 程序的开始点,没有返回值
main: 固定名称
String args[]: 控制台参数
static的实际应用
-
不管多少个对象都使用同一个static属性
-
避免实例化对象调用方法的限制
应用1:实现实例化对象的个数统计
class Book{
private static int num =0;
public Book(){
numm++;
}
}
应用2:实现属性的自动设置
比如无参的类构造方法可以让static声明的属性作为默认数据使用,不用手动输入参数
这样结果不会是null
代码块
实际开发中不建议使用代码块,他会破坏程序结构
-
普通代码块
代码块写在普通方法里
普通代码块中定义的变量是局部变量,只有代码块内能够使用
全局变量的局部变量是一种相对概念
-
构造块
代码块中卸载一个类里
**构造块在每一次实例化对象时必被调用,且优于构造方法执行
-
静态块
代码块使用static声明
static{ }
非主类中有静态块时如果有多个实例化对象产生,静态块有限调用,且只调用一次,一般用于Static属性的初始化
在主类中有静态块时,静态块优于主方法调用
jdk1.7之前,静态块可以替换主方法使用
-
同步代码块
等待多线程时
内部类
内部类是一种程序扩充
一. 一个类内部继续定义其他内部结构类
一个类除了属性和方法外,还有存在其他类的结构,并且内部类也可以定义在方法或者代码块里。
缺点:破坏了类的结构性
优点:轻松访问外部类的私有属性
如果拆成两个类,有些引用传递会非常复杂
内部类的存在是为了方便外部类的操作而存在的,非特殊情况不编写内部类
外部类可以直接调用内部类:对象.属性,来进行私有属性操作
内部类想在外部实例化:
外部类.内部类 对象 = new 外部类().new 内部类();
进行两层构造
内部类需要使用外部类中的属性,所有属性只有实例化后才会分配空间,所以在实例化内部类对象首先要实例化外部类对象
如果内部类只想被外部类访问而不想被外部调用,那么就使用private声明私有内部类
二. static内部类
不受外部类实例化对象控制的内部类,如果对内部类使用static关键字,该类就会变成"外部类",并且只能访问外部类中定义的static操作
相当于定义了一个外部类
如果想取得该种内部类的实例化
外部类.内部类 对象 = new 外部类.内部类();
不需要再实例化外部类
如果发现工程中类的前面有’’.’'考虑是不是内部类
三. 方法中定义的内部类
开发过程中,普通方法中定义内部类是最多的
从JDK1.8开始,内部类可以直接访问其所定义方法的参数和变量
JDK1.7以前,参数和变量前要用final关键字声明才能被内部类直接访问(取消和Lambda表达式有关)
链表
差不多
本章中的链表不完全
后面学完继承多态泛型后有更好的解决方案
package Linkedlist;
public class LinkedList {
/**
* 链表节点类
*/
class Node {
private String data;
private Node next;
/**
* 链表节点构造方法
* @param data
*/
public Node(String data) {
this.data = data;
}
/**
* 构造新节点
* @param newNode
*/
public void addNode(Node newNode) {
if (this.next == null){
this.next = newNode;
}else{
this.next.addNode(newNode); //递归向后查找,一直到链表尾部
}
}
/**
* 链表中查找数据
* @param data
* @return
*/
public boolean containsNode(String data){
if(data.equals(this.data)){
return true;
}else {
if(this.next!=null){
return this.next.containsNode(data);
}else {
return false; //递归向后查找,一直到链表尾部
}
}
}
/**
* 按索引获取数据
* @param index
* @return
*/
public String getIndex(int index) {
if(LinkedList.this.foot++ == index){ //foot要自增以匹配数据索引
return this.data;
}else {
return this.next.getIndex(index);
}
}
/**
* 此处处理一般性非根节点删除
* @param previous
* @param data
*/
public void removeNode(Node previous, String data) {
if(data.equals(this.data)){
previous.next = this.next; //空出当前节点,将前驱节点连接到后继节点
}else {
this.next.removeNode(this,data);
}
}
/**
* 将链表节点转换成数组节点
*/
public void toArrayNode() {
LinkedList.this.retArray[LinkedList.this.foot++]=this.data;
if(this.next!=null){
this.next.toArrayNode();
}
}
public void setNode(int index, String data) {
if(LinkedList.this.foot++ == index){
this.data = data;
}else {
this.next.setNode(index,data);
}
}
}
/******************************************************************************/
private Node root; //根节点
private int count = 0; //计数
private int foot = 0; //序号标记
private String[] retArray; //字符数组
/**
* 添加节点
* @param data
*/
public void add(String data){
if(data ==null){
return;
}
Node newNode = new Node(data);
if(this.root == null){
this.root = newNode;
}else{
this.root.addNode(newNode);
}
count++;
}
/**
* 返回链表长度
* @return
*/
public int size(){
return count;
}
/**
* 判断是否为空
* @return
*/
public boolean isEmpty(){
return this.count==0;
}
/**
* 封装的查找方法
* @param data
* @return
*/
public boolean contains(String data){
if(data==null||this.root==null){
return false;
}
return this.root.containsNode(data); //调用Node的查找方法
}
/**
* 按索引获取数据
* @param index
* @return
*/
public String get(int index){
if(index>this.count){
return null;
}
foot = 0;
return root.getIndex(index);
}
public void set(int index,String data){
if(index>this.count){
return;
}
this.foot=0;
this.root.setNode(index,data);
}
/**
* 此处删除包含了删除节点是根节点的情况
* @param data
*/
public void remove(String data){
if(this.contains(data)){
if(data.equals(this.root.data)){
this.root = this.root.next;
}else {
this.root.next.removeNode(this.root,data);
}
}
count--;
}
/**
* 将字符串链表转换成字符串数组
* @return
*/
public String[] toArray(){
if(this.root==null){
return null;
}
this.foot=0;
this.retArray = new String[this.count];
this.root.toArrayNode();
return this.retArray;
}
/**
* 清空链表
*/
public void clear(){
root = null;
this.count = 0;
}
}