上周用数组基于面向对象完成了一个学生管理系统,发现其中有很多弊端,例如,用数组每次的长度只能是不变的,数组如果长度过大,会造成空间上不必要的浪费,太小则造成数据存不下。
逻辑上实现动态数组
思路:在创建MyArrayList对象时,初始化一个长度为5 的数组,在添加商品时,会先对数组的容量进行判断, 当前数组的容量大于等于初始数组容量时,会对其容量扩增(1.5倍),然后通过数组拷贝进行让原有数组里的数据添加到新数组中。
import com.day04.example.Goods;
public class MyArrayList {
/**商品*/
private Goods[] arr;
/**索引*/
private int index;
/**
* 创建对象时初始化长度为5的数组
*/
public MyArrayList() {
arr = new Goods[5];
}
/**
* 数组容量增加
*/
public MyArrayList(int capatity) {
arr = new Goods[capatity];
}
/**
* 添加商品
* @param good
*/
public void add(Goods good) {
ensureCapacity();
arr[index++] = good;
}
/***
* 对初始数组容量做判断
*/
private void ensureCapacity() {
if(index >= arr.length) {
grow();
}
}
/**
* 对原来数组容量进行扩增
*/
private void grow() {
int len = arr.length;
//对后来数组扩增1.5倍
Goods[] good = new Goods[len+(len >> 1)];
//将原有数组的长度加到新数组中
System.arraycopy(arr, 0, good, 0, len);
arr = good;
}
/**
* 返回索引的元素
* @param i
* @return
*/
public Goods get(int i) {
return arr[i];
}
/**
* 返回索引位置
* @return
*/
public int size() {
return index;
}
public void remove(int i) {
System.arraycopy(arr, i + 1 , arr, i , arr.length-(i+1));
}
}
实现动态数组后,对数据的增删改查更加灵活
如下部门
员工管理系统
员工类
package com.day02.example;
public class Emp {
/**工号*/
private int eid;
/**姓名*/
private String ename;
/**性别*/
private char sex;
/**职位*/
private String position;
/**年龄*/
private int age;
/**月薪*/
private double sal;
/**部门 */
private Dept dept;
public Emp() {
super();
// TODO Auto-generated constructor stub
}
public Emp(int eid, String ename, char sex, String position, int age, double sal,Dept dept) {
super();
this.eid = eid;
this.ename = ename;
this.sex = sex;
this.position = position;
this.age = age;
this.sal = sal;
this.dept = dept;
}
public int getEid() {
return eid;
}
public void setEid(int eid) {
this.eid = eid;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Emp [eid=" + eid + ", ename=" + ename + ", sex=" + sex + ", position=" + position + ", age=" + age
+ ", sal=" + sal + ", dept=" + dept + "]";
}
}
部门类
package com.day02.example;
public class Dept {
/**编号*/
private int did;
/**部门名*/
private String dname;
/**部门介绍*/
private String intorduce;
/**分机号*/
private int number;
public Dept() {
super();
// TODO Auto-generated constructor stub
}
public Dept(int did, String dname, String intorduce, int number) {
super();
this.did = did;
this.dname = dname;
this.intorduce = intorduce;
this.number = number;
}
public int getDid() {
return did;
}
public void setDid(int did) {
this.did = did;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getIntorduce() {
return intorduce;
}
public void setIntorduce(String intorduce) {
this.intorduce = intorduce;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public String toString() {
return "Dept [did=" + did + ", dname=" + dname + ", intorduce=" + intorduce + ", number=" + number + ", emp="
;
}
}
管理系统
package com.day02.example;
import java.util.ArrayList;
public class Manage {
static ArrayList<Emp> list = new ArrayList<>();
/**
* 向各个部门中添加若干员工
* @param emp 员工对象
* @return 添加成功/失败返回布尔值
*/
public boolean addEmp(Emp emp) {
return list.add(emp);
}
/**
* 查询所有信息和部门信息
* @return 返回一个员工集合
*/
public ArrayList<Emp> showAll() {
return list;
}
/**
* 根据工号查询员工信息
* @param id 员工id
*/
public Emp selectEmp(int id) {
for (Emp emp : list) {
if (emp.getEid() == id) {
return emp;
}
}
return null;
}
/**
* 根据指定工号修改员工薪资
* @param e
*/
public boolean updateEmp(Emp e) {
for (Emp emp : list) {
if (emp != null && emp.getEid() == e.getEid()) {
emp.setSal(e.getSal());
return true;
}
}
return false;
}
/**
* 根据部门号查出所有员工
* @param Dept
*/
public ArrayList<Emp> selectAllEmp(int did) {
ArrayList<Emp> emps = new ArrayList<>();
for (Emp emp : emps) {
if (emp.getDept().getDid() == did) {
return emps;
}
}
return null;
}
}
测试类
package com.day02.example;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
Manage m = new Manage();
Dept dept = new Dept(1, "研发部", "做实验的", 1001);
Dept dept1 = new Dept(2, "开发部", "开发", 1002);
Dept dept2 = new Dept(3, "人事部", "做人事的", 1003);
Emp e1 = new Emp(1, "张三", '男', "员工", 23, 6000, dept);
Emp e2 = new Emp(2, "李四", '男', "员工", 24, 6500, dept);
Emp e3 = new Emp(3, "王二", '男', "员工", 23, 6040, dept2);
Emp e4 = new Emp(1, "李白", '男', "员工", 23, 4500, dept2);
Emp e5 = new Emp(2, "貂蝉", '女', "员工", 23, 6930, dept1);
Emp e6 = new Emp(3, "西施", '女', "员工", 24, 6700, dept1);
m.addEmp(e1);
m.addEmp(e2);
m.addEmp(e3);
m.addEmp(e4);
m.addEmp(e5);
m.addEmp(e6);
ArrayList<Emp> list = m.showAll();
for (Emp emp : list) {
System.out.println(emp);
}
System.out.println("=============================");
// 根据id查看员工信息
Emp emp2 = m.selectEmp(1);
if(emp2 != null) {
System.out.println(emp2);
}else {
System.out.println("该员工不存在");
}
System.out.println("=============================");
Emp emp = new Emp();
emp.setEid(3);
emp.setSal(7054);
boolean b = m.updateEmp(emp);
if(b) {
System.out.println("修改成功");
System.out.println(m.selectEmp(3));
}else {
System.out.println("修改失败 该员工不存在");
}
}
}
测试结果
面向对象最重要特征之——多态
多态:字面意思,即多种形态,在子类实现父类或者子类继承父类时,子类重写父类方法时,子类对其方法不满意,对该方法进行修改,从而在调用这个方法时,变现出不同的形态叫多态
例如:
public class Animal {
public void bark() {
System.out.println("别叫");
}
public static void main(String[] args) {
// 父类对象指向子类对象
Animal dog = new Dog();
dog.bark();
//子类对象指向父类对象,仅当对象为父类引用时
Dog dog1 = (Dog) dog;
dog1.bark();
}
}
class Dog extends Animal {
@Override
public void bark() {
System.out.println("汪汪汪");
}
}
String类、StrringBuffer、StringBuilder的区别
String在创建后,无法改变,如果强加修改,会重新创建对象,会造成空间上的浪费。而StringBuffer和StringBuilder不用二次创建对象,只需要使用append方法在后面追加即可,并且在效率上优于String.
StringBUffer与StringBuilder:在单线程中,两者效率无明显差异,但在多线程中,StringBuffer相对安全,但StringBulder稍微快一点
Static关键字
static在java中即是关键字,也是修饰符,被static修饰的属性叫类属性,也叫静态属性,被static修饰的方法叫类方法,也叫静态方法,被static修饰的初始块也叫静态游离块
package com.day02;
public class Test{
String msg = "hello";
static {
Test t = new Test();
t.msg = "world";
System.out.println(t.msg);
}
//离块作用于构造器执行前,执行一些初始化操作
{
msg="helloworld";
}
public Test() {
msg = "你好世界";
}
public static void main(String[] args) {
//类加载时会自动执行静态初始化块中的内容,即便main方法中没有编写任何内容
}
}
由此得知
static块,游离块,构造器的执行顺序
- 首先执行static块,并且只执行一次
- 其次对象创建时先执行游离块然后才执行构造器
- 游离块的执行次数取决于构造器的调用次数
设计模式之——单例模式
简单来说,单例模式就是在程序执行过程中,始终都只有一个对象。单例模式分为两种
饿汉式:在类加载时创建对(以空间换时间)
private static Singleton2 instance = new Singleton2();
private Singleton2() {
public static Singleton2 newInstance() {
return instance;
}
懒汉式:在需要对象时创建,(以时间换空间)
private static Singleton instance; //15db9742
//构造器私有化,不允许外界随意访问(不允许随便创建对象)
private Singleton() {}
public static Singleton newInstance() {
//判断对象是否已创建
if(instance == null) {
instance = new Singleton();
}
return instance;
}
图形界面(GUI)
public class MyFrame extends JFrame{
public MyFrame() {
//设置窗口标题
setTitle("双十一欢乐大抽奖");
//设置窗口大小
setSize(800, 600);
//设置窗口居中显示
setLocationRelativeTo(null);
//将窗口设置为不可改变大小的
setResizable(false);
//点击退出即关闭虚拟机
setDefaultCloseOperation(EXIT_ON_CLOSE);
initUI();
setVisible(true);
}
private void initUI() {
//创建文本控件
JLabel label = new JLabel();
//设置文本内容
label.setText("恭喜中奖!");
//设置字体、字号、字体大小、颜色等
label.setFont(new Font("楷体", Font.BOLD, 50));
label.setForeground(Color.ORANGE);
//将控件显示到窗口中(多态)
add(label);
}
public static void main(String[] args) {
new MyFrame();
}
}
抽象类和接口
抽象类:被abstract修饰的类叫抽象类,通常里面会有抽象方法, 也是用abstract修饰,只是抽象方法没得方法体。继承抽象类必须实现抽象类中的所有方法,父类到最终的子类都不能创建对象,失去意义。
package com.day04.abstact;
public abstract class Animal {
private String name;
public abstract void eat();
public abstract void sleep();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.day04.abstact;
public class Dog extends Animal{
@Override
public void sleep() {
System.out.println("睡觉");
}
@Override
public void eat() {
System.out.println("啃骨头");
}
}
接口
被interface修饰的叫接口,不能创建对象,但是可以被实现(implements,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
抽象类和接口的区别
- 抽象类是用extends来进行扩展的,接口是用implment来扩展的
- 抽象类之间只能单继承,接口之间可以多继承。
- 抽象类可以定义构造方法,接口则没有构造方法
- 抽象类可以同时实现多个接口,但接口只能继承一个抽象类
java内部类
- 成员内部类
- 局部内部类
- 静态内部类
- 匿名内部类(最为常见)
成员内部类
package com.day05.innerclass;
import java.awt.Dimension;
import java.awt.Font;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
* 成员内部类
* @author 承蒙
*/
public class People extends JFrame{
public static void main(String[] args) {
People.Body b = new People().new Body();
b.m("张三");
People p = new People();
p.m();
}
public void m() {
System.out.println("成员方法");
}
private JFrame j;
public class Body extends ArrayList{
public void m(String m) {
j = new JFrame();
j.setTitle("成员内部类");
j.setSize(new Dimension(300,400));
JLabel l = new JLabel(m);
l.setFont(new Font("微软雅黑", Font.BOLD, 23));
j.add(l);
j.setVisible(true);
System.out.println("成员内部类");
}
}
}
局部内部类
package com.day05.innerclass;
/**
* 局部内部类
* @author 承蒙
*/
public class User {
public void login() {
int i = 10;
class M{
public void m() {
System.out.println("张三先生"+i);
}
}
M m = new M();
m.m();
}
public static void main(String[] args) {
User user = new User();
user.login();
}
}
静态内部类
package com.day05.innerclass;
/**
* 静态内部类
* @author 承蒙
*
*/
public class StaticClass {
public static void main(String[] args) {
StaticClass.Cache c = new Cache();
c.m2();
StaticClass.Cache.m();
}
public static class Cache {
private static String msg = "静态内部类";
public static void m() {
System.out.println(msg+"方法产生");
}
public void m2(){
System.out.println("普通方法产生");
}
}
}
匿名内部类
package com.day05.innerclass;
import java.util.ArrayList;
/**
* 匿名内部类
*
* @author 承蒙
*/
public class Test {
ArrayList<Integer> list = new ArrayList<Integer>() {
{
add(10);
add(20);
add(30);
}
};
public void show() {
System.out.println(list);
}
public static void main(String[] args) {
Animal a = new Animal() {
public void eat() {
System.out.println("吃毛线");
m();
}
public void m() {
System.out.println("吃毛线1 ");
}
};
a.eat();
Flyable f = new Flyable() {
public void fly() {
System.out.println("扶摇直上九万里");
f1();
}2
public void f1() {
System.out.println("来吧 展翅");
}
};
f.fly();
new Test().show();
}
}