第二部分 面向对象篇
第7章 类与对象
7.1 面向过程与面向对象思想
面向过程
当我们在解决一个问题时,会按照预先设定的想法和步骤,一步一步去实现,在这里每一步具体的实现中都需要我们自己去亲自实现和操作。
举个例子:自己做->买菜->洗菜->切菜->炒菜->吃
我们的角色是: 执行者
特点:费时间、费精力、结果也不一定完美
面向对象
当我们在解决一个问题时,可以去找具有相对应的功能的事物帮着我们去解决问题,至于这个事物如何工作,与我们无关,我们只看结果,不关心解决流程。
举个例子:叫外卖->下单->餐馆做饭->骑手送餐->吃
我们的角色是: 指挥者
特点:节省时间,节省精力,结果相对完美
面向过程是面向对象的基础,问题可以自己不解决托给别人解决,别人也可以在再托给别人,但最
终,事情必须要处理掉,一旦处理就是面向过程
面向对象和面向过程差异
面向对象是一种符合人们思考习惯的思想
面向过程中更多的体现是执行者,面向对象中更多的体现是指挥者。
面向对象可以将复杂的问题进行简单化,更加贴近真实的社会场景
7.2 类与对象的关系
什么是对象
面向对象编程语言主要是使用对象们来进行相关的编程。对象,万事万物中存在的每一个实例,一个电脑、一个手机、一个人、抖音里的一个短视频、支付宝里的一个交易记录、淘宝里的订单。
如何去描述一个对象的内容?
对象的属性:就是对象的相关参数,可以直接用数据来衡量的一些特征——常量|变量来表示(成员变量)
对象的行为:就是过将对象的属性进行联动,产生出一系列的动作或行为——函数(成员函数)
什么是类
类是那些具有相同属性特征和行为的对象们的统称。对象就是该类描述下具体存在的一个事物。
示例:定义一个圆类
//这是一个专门用于程序执行的类,因为里面有主函数
//包含主函数的类 统称为 主类
//当然 实体类中也可以包含主函数
public class Sample {
public static void main(String[] args) {
Circle c1 = new Circle();
System.out.println(c1.radius);
c1.radius = 10;
System.out.println(c1.getArea());
Circle c2 = new Circle();
System.out.println(c2.radius);
System.out.println(c2.getArea());
Circle c3 = new Circle();
c3.type = 2;
c3.setRadius(20);
System.out.println(c3.getPerimeter());
}
}
//这是用于描述圆的一个类
//类似于这种专门描述事物的类 - 实体类
class Circle {
//属性
double radius;
double type = 1;
//行为
public double getArea() {
return Math.PI * radius * radius;
}
public double getPerimeter() {
return 2 * Math.PI * radius;
}
public void setRadius(double newRadius) {
radius = newRadius;
}
}
示例:定义一个电视机类
public class Sample {
public static void main(String[] args) {
TV tv1 = new TV();
tv1.turnOn();
tv1.setChannel(12);
tv1.setChannel(300);
tv1.channelUp();
tv1.channelDown();
tv1.showStatues();
TV tv2 = new TV();
tv2.showStatues();
}
}
class TV {
//属性
int channel = 1;
int volumeLevel = 3;
boolean on;
//行为
public void turnOn() {
on = true;
}
public void turnOff() {
on = false;
}
public void setChannel(int newChannel) {
if (on) {
if (newChannel > 120) {
channel = 120;
} else if (newChannel < 1) {
channel = 1;
} else {
channel = newChannel;
}
System.out.println("电视选台为:" + channel);
}
}
public void setVolumeLevel(int newVolumeLevel) {
if (on) {
if (newVolumeLevel > 7) {
volumeLevel = 7;
} else if (newVolumeLevel < 1) {
volumeLevel = 1;
} else {
volumeLevel = newVolumeLevel;
}
System.out.println("电视音量为:" + volumeLevel);
}
}
public void channelUp() {
if (on) {
channel++;
if (channel > 120) {
channel = 1;
}
System.out.println("电视选台为:" + channel);
}
}
public void channelDown() {
if (on) {
channel--;
if (channel == 0) {
channel = 120;
}
System.out.println("电视选台为:" + channel);
}
}
public void volumeUp() {
if (on) {
volumeLevel++;
if (volumeLevel > 7) {
volumeLevel = 7;
}
System.out.println("电视音量为:" + volumeLevel);
}
}
public void volumeDown() {
if (on) {
volumeLevel--;
if (volumeLevel < 1) {
volumeLevel = 1;
}
System.out.println("电视音量为:" + volumeLevel);
}
}
public void showStatues() {
if (on) {
System.out.println("电视已开机");
System.out.println("频道:" + channel);
System.out.println("音量:" + volumeLevel);
} else {
System.out.println("电视已关机");
}
}
}
7.3 封装与private关键字
封装-包装
常见的封装体现
函数
类
封装有什么好处?
提高了安全性
向外界隐藏了一些不需要被外界获知的内容
提高了代码的复用性
也是面向对象的三大特点之一:封装 继承 多态
封装不是封死,还是要向外提供一些访问内部内容的方法
private关键字,属于权限关键字 public protected 默认不写 private
private可以作用在对象属性和行为上,外界在创建对象后,则不能访问被private修饰的内容
public class Sample {
public static void main(String[] args) {
Person p1 = new Person();
/*
p1.name = "狗蛋";
p1.age = 10;
p1.speak();
p1.age = -10;
p1.speak();
*/
/*
System.out.println(p1.age); //比较无辜
*/
p1.setName("旺财");
p1.setName("小强");
p1.setAge(-10);
p1.setAge(10);
p1.speak();
}
}
class Person {
private String name;
private int age;
private int mathScore;
public void speak() {
System.out.println("我是" + name + ",我今年" + age + "岁");
}
public void setMathScore(int newMathScore) {
mathScore = newMathScore;
}
public void setName(String newName) {
if (newName.equals("旺财")) {
name = "哈士奇";
} else {
name = newName;
}
}
public void setAge(int newAge) {
if (newAge < 0) {
age = 0;
} else {
age = newAge;
}
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
总结:
1、类中不需要对外界提供的内容,最好都私有化
2、如果后续真的需要对私有的内容进行更改,最好加上setXXX修改器,getXXX访问器
不可变对象或类
就是指其内部的数据都是私有的,没有向外界提供任何修改内部的方法(String)
1、所有的数据都是私有的
2、没有修改器的方法
7.4 局部变量与成员变量
public class Sample {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("小强");
p1.setAge(10);
p1.speak();
}
}
class Person {
private String name;
private int age;
public void speak() {
System.out.println("我是" + name + ",我今年" + age + "岁");
}
public void setName(String name) {
if (name.equals("旺财")) {
this.name = "哈士奇";
} else {
this.name = name;
}
}
public void setAge(int age) {
if (age < 0) {
this.age = 0;
} else {
this.age = age;
}
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
代码执行流程:
- javac 编译Sample.java源代码 生成Sample.class和Person.class两个字节码文件
- 如果java Person ,运行Person字节码文件,则报错,没有主函数不是主类
- 只能java Sample 运行Sample程序
- 将相关的字节码(Sample.class Person.class)文件加载进JVM中内存下的方法区
- 在方法区中Sample字节码所在的区域里,找主函数,将主函数的栈帧加载进栈内存开始运行
- 开始执行主函数的第一句代码,创建Person对象
- 在堆内存中开辟一个空间并分配地址,在该空间中创建成员变量并默认初始化
- 在主函数空间中创建局部变量p1,并将该对象的地址传给p1
- 接着执行主函数第二句代码,调用p1对象的setName方法
- 从方法区中的Person里,将setName函数栈帧加载进栈,主函数暂停运行
- setName进栈后,创建局部变量name(形参),并将实参“小强”这个字符串在字符串常量池
中的地址赋予name - 因为setName成员函数只有一份在方法区中Person所属区间里,之后可以被多个同类对象调
用,为了区分到底是哪个对象调用的该方法,所以在每一个成员函数中,都会有一个隐藏的
关键字数据 this ,this相当于一个变量来存储当前对象的地址。(当前对象的引用) - 执行setName中的内容,如果数据没有问题的话,就将局部变量的值赋值个当前对象的成员
变量 - setName函数执行最后一行隐藏的return,表示函数结束并弹栈
- 主函数成为当前栈顶,继续执行
- 执行p1调用setAge函数,从方法区中Person所属空间里找setAge这一段代码,将该函数栈帧加
载进栈内存成为新的栈顶,则主函数暂停,该函数运行。先创建形参age的局部变量,接收实
参传来的值10,为了区分对象的调用关系,自带this关键字数据,this存的还是p1的地址,如
果age没有问题,则将10传给this所指向的对象中age这个成员变量。setAge执行最后一行隐藏
的return,表示函数结束并弹栈 - 主函数称为新的栈顶继续执行,调用p1的speak函数进栈
- 在方法区中Person字节码所属空间里读取speak代码,将该栈帧加载进占内存中,主函数暂
停,该函数执行,无形参只能表示没有形参的局部变量,但是在函数内部也可以创建其他的
局部变量,并且有this关键数据存的是p1的地址,然后去打印name和age,由于speak空间中已经没有其他名为name或age的局部变量,所以找不到,接着找this对象中的数据,找到了则
打印。直至函数结束并弹栈 - 主函数又称为栈顶,也没有代码了,执行隐藏的return,主函数弹栈,表示程序结束。
- 局部变量和成员变量有什么区别?
生命周期
成员变量随着对象的创建而创建,随着对象的消亡而消失
局部变量随着函数的进栈而创建,随着函数的出栈而消失
存储位置
成员变量在堆内存中对象所属空间里
局部变量在栈内存中函数所属空间里
定义位置
成员函数在类中,函数外定义
局部变量在函数中定义
初始化
成员变量有默认初始化
局部变量必须初始化之后再调用
7.5 构造函数
回顾一下之前的几个问题:
我们之间在创建对象的时候,对象的成员变量是在对象创建之后通过setXXX修改器赋值
对对象成员变量的赋值可以进行可选操作
什么是构造函数:构造函数主要是在创建对象的时候执行的函数,在该函数中也可对成员变量进行一些操作
构造函数的格式
权限修饰符 类名(参数列表) {
构造函数的代码块
}
构造函数没有返回值
构造函数的名称必须是类名
参数列表可选的,构造函数是可以重载的
虽然构造函数没有返回值,还是存在return关键字的
当我们的类中没有定义任何构造函数时,会有一个默认隐藏的无参构造函数存在
构造函数和成员函数一样,为了区分对象的调用,构造函数自带this关键字数据
构造函数需要注意的问题
如果一旦定义其他参数列表的构造函数的话,这个隐藏的无参构造函数就会消失,所建议手写
出来
构造函数只有在创建对象的时候执行,当对象创建完毕之后,该对象的构造函数则不能执行
成员函数只有在对象创建之后才能执行
成员函数能否直接调用构造函数?不能够的,报找不到符号错误 会误认为是同名的成员函数
构造函数能否直接调用成员函数呢?能够,但是 这些成员函数一般是构造函数的部分代码片段被
切割出来了而已,从语意上而言,不属于对象的特有行为(也有特例),所以这些函数长得样子就是
成员函数的样子,但没有必要向外界提供访问,所以加上private
构造函数能否直接调用构造函数呢?可以,但是必须通过 this(参数列表) ,需要注意的是,
构造函数可以单向调用其他构造函数,但坚决不能出现回调。
构造函数是在创建对象的时候执行的,可以在期间对成员变量进行初始化,问:setXXX还需要
不?看需求,如果后期成员变量需要修改,则提供setXXX修改器
public class Sample {
public static void main(String[] args) {
Person p = new Person();//new 构造函数;
p.setName("旺财");
p.setAge(10);
p.speak();
Person p2 = new Person();//new 构造函数;
p2.setName("小强");
p2.setAge(20);
p2.speak();
Person p3 = new Person("如花",40);
p3.speak();
p3.test();
//p3.part();
Car car1 = new Car();
Car car2 = new Car(4);
Car car3 = new Car(4,"红色");
Car car4 = new Car(8,"武士黑",20);
car1.run();
car2.run();
car3.run();
car4.run();
}
}
class Car {
private int wheel = 4;
private String color;
private int weight;
public Car(){
}
public Car(int wheel) {
this(wheel,null,0);
}
public Car(int wheel,String color) {
this(wheel,color,0);
}
public Car(int wheel,String color,int weight) {
this.wheel = wheel;
this.color = color;
this.weight = weight;
//this();//递归构造器调用
}
public void run() {
System.out.println(wheel + ":" + color + ":" + weight);
}
//这个不是重载 Car(int)已经存在了(wheel)
/*
public Car(int weight) {
}
*/
}
class Person {
private String name;
private int age;
//这就是隐藏的构造函数
public Person() {
System.out.println("一个Person创建出来了!");
part();
part();
part();
part();
}
//语意
private void part() {
System.out.println("100行代码");
}
public Person(String name,int age) {
System.out.println("一个Person创建出来了!");
this.name = name;
this.age = age;
}
public void test() {
Person();//实际上这一段代码并不表示调用无参构造函数
//而表示去调用名字为Person的成员函数!
}
public void Person() {
System.out.println("没想到吧!");
}
public void speak() {
System.out.println(name + ":" + age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
关于成员变量初始化的问题
成员变量的初始化经历了三个步骤:默认初始化(大家默认都是0值),显式初始化(大家的值都
一样),针对性初始化(大家的值可选)
7.6 对象的创建流程及内存图解
示例:定义一个栈
public class Sample {
public static void main(String[] args) {
Stack stack = new Stack();
System.out.println(stack);
for (int i = 1; i <= 10; i++) {
stack.push(i);
}
System.out.println(stack.toString());
System.out.println(stack.pop());
System.out.println(stack);
System.out.println(stack.peek());
}
}
class Stack {
private int[] data; //栈的容器
private int top = -1; //栈顶元素的角标 开始为-1
private static int capacity = 10; //栈容器的最大容量 top + 1 <= capacity
public Stack() {
this(capacity);
}
public Stack(int capacity) {
data = new int[capacity];
}
//向栈中进栈一个元素e
public void push(int e) {
if (size() == data.length) {
//需要扩容
resize(data.length * 2);
}
top++;
data[top] = e;
}
public int pop() {
if (isEmpty()) {
System.out.println(">>>栈已空!无法弹出元素!");
return -1; //表示出错
}
int e = data[top];
top--;
if (size() == data.length / 4 && data.length > capacity) {
resize(data.length / 2);
}
return e;
}
public int peek() {
if (isEmpty()) {
System.out.println(">>>栈已空!无法获取栈顶元素!");
return -1; //表示出错
}
return data[top];
}
private void resize(int len) {
int[] arr = new int[len];
for (int i = 0; i <= top; i++) {
arr[i] = data[i];
}
data = arr;
}
//获取有效元素的个数
public int size() {
return top + 1;
}
//判断栈是否为空
public boolean isEmpty() {
return top == -1;
}
//打印一个对象 其实就是在打印这个对象toString方法的结果
public String toString() {
if (isEmpty()) {
return "[]";
} else {
String s = "[";
for (int i = 0; i <= top; i++) {
if (i == top) {
s = s + data[i] + "]";
} else {
s = s + data[i] + ", ";
}
}
return s;
}
}
}
示例:模拟吃鸡
public class Sample {
public static void main(String[] args) {
Player p1 = new Player("老王",100);
Player p2 = new Player("老李",100);
p1.shootEnemy(p2);
Gun gun = new Gun();
p1.holdGun(gun);
p1.shootEnemy(p2);
Clip clip = new Clip();
for (int i = 1; i <= 30; i++) {
clip.pushBullet(new Bullet());
}
p1.loadClip(clip);
for (int i = 1; i <= 30; i++) {
p1.shootEnemy(p2);
}
p1.shootEnemy(p2);
}
}
class Player {
private String name;
private int blood;
private Gun gun;
public Player() {}
public Player(String name,int blood) {
this.name = name;
this.blood = blood;
}
public Player(String name,int blood,Gun gun) {
this.name = name;
this.blood = blood;
this.gun = gun;
}
public void holdGun(Gun gun) {
this.gun = gun;
}
public void shootEnemy(Player enemy) {
if (gun == null) {
System.out.println(">>>玩家信息:没有枪,开P");
} else {
System.out.printf(">>>玩家信息:%s向%s开了一枪\n",name,enemy.name);
gun.shootEnemy(enemy);
}
}
public void loadClip(Clip clip) {
if (gun == null) {
System.out.println(">>>玩家信息:没抢,装不了弹夹");
} else {
gun.loadClip(clip);
}
}
public void damage(int hurt) {
if (blood == 0) {
System.out.println(">>>玩家信息:" + name + "已经成盒,请勿鞭尸");
} else {
blood -= hurt;
if (blood > 0) {
System.out.println(">>>玩家信息:" + name + "掉血" + hurt + ",剩余" +
blood);
} else {
blood = 0;
System.out.println(">>>玩家信息:" + name + "已经成盒");
}
}
}
}
class Gun {
private Clip clip;
public Gun() {
this(null);
}
public Gun(Clip clip) {
this.clip = clip;
}
public void loadClip(Clip clip) {
this.clip = clip;
}
public void shootEnemy(Player enemy) {
if (clip == null) {
System.out.println(">>>枪信息:没有弹夹,开了个空枪");
return;
}
Bullet bullet = clip.popBullet();
if (bullet == null) {
System.out.println(">>>枪信息:弹夹没子弹 开了个空枪");
} else {
bullet.hitEnemy(enemy);
}
}
}
class Clip {
private int capacity = 30;
private int surplus = 0;
private Bullet[] magazine;
public Clip() {
this(30);
}
public Clip(int capacity) {
this.capacity = capacity;
magazine = new Bullet[capacity];
}
public void pushBullet(Bullet bullet) {
if (surplus == capacity) {
System.out.println(">>>弹夹信息:弹夹已满,无法装入子弹");
return;
}
magazine[surplus] = bullet;
surplus++;
showClip();
}
public Bullet popBullet() {
if (surplus == 0) {
System.out.println(">>>弹夹信息:弹夹已空,无法弹出子弹");
return null;
}
Bullet bullet = magazine[surplus - 1];
surplus--;
showClip();
return bullet;
}
public void showClip() {
System.out.printf(">>>弹夹信息:%d/%d\n",surplus,capacity);
}
}
class Bullet {
private int hurt = 10;
public Bullet(){}
public Bullet(int hurt) {
this.hurt = hurt;
}
public void hitEnemy(Player enemy) {
enemy.damage(hurt);
}
}
7.7 static关键字
静态关键字
主函数有static修饰-静态函数,全局变量static修饰
主要用于修饰成员变量(对象的特有属性)和成员函数,变为静态变量和静态函数
静态变量最大的特点是同类下多个对象之间的共有属性
什么时候定义静态变量呢?在同一类下,多个对象之间有相同的属性和值,那么就可以将该属性和值从成员变量变为静态变量,目的就是为了节省空间。
什么时候去定义静态函数呢?只有一点,当一个成员函数不访问成员时,即可定义为静态函数!
静态函数一旦定义出来,可以直接用类名去调用(Math.sqrt()),当然也可以通过创建对象来去调用静态函数!
静态优先于对象存在,且在同一类中,静态无法访问非静态(成员),非静态是可以访问静态
静态函数中是否还存在this?不存在了!
当通过对象去调用一个属性时,先找成员,再找静态,最后找父类
如果从成员函数中去调用一个属性时,先找局部,再找成员,再找静态,最后找父类
好处:
1、节省堆内存中的空间
2、可以不用费力气去创建对象来调用功能
3、可以对类进行一些初始操作(结合代码块来做)
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
Chinese c1 = new Chinese();
Chinese c2 = new Chinese();
Chinese c3 = new Chinese();
System.out.println(c1.country);
System.out.println(Chinese.country);
c1.show();
Chinese.show();
/*
Chinese.test();
*/
}
}
class Chinese {
String name;
int age;
static String country;
//静态代码块
static {
country = "China";
System.out.println("init....");
}
Chinese() {
System.out.println("Chinese....");
}
public void test(){
int num = 10;
System.out.println(num + name + country);
}
public static void show() {
/*
//无法从静态上下文中引用非静态 方法 test()
test();
//无法从静态上下文中引用非静态 变量 name
System.out.println("show...." + name);
*/
}
}
7.8 静态变量与成员变量
存储位置
成员变量存储在堆内存中对象所属空间里
静态变量存储在静态方法区中对应的字节码空间里
生命周期
成员变量随着对象的创建而创建,随着对象的消亡而消亡
静态变量随着类的加载而存在,随着程序的结束而消失
所属不同
成员变量属于对象的,称之为是对象的特有属性
静态变量属于类的,称之为是类的属性,或者叫对象的共有属性
调用方式不用
成员变量在外界必须通过创建对象来调用,内部的话成员函数可以直接调用成员变量,但是静态函数不
能直接调用成员变量,如果非要在静态函数中调用成员的话,只能创建对象,通过对象来调用
静态变量在外界可以通过对象调用,也可以通过类来调用,内部的话静态函数/成员函数可以调用静态
变量
public class Demo {
public static void main(String[] args) {
//StackOverFlowError 栈内存溢出
A a = new A();
System.out.println(a == a.a);
System.out.println(a.a == a.a.a);
}
}
class A {
//OutOfMemoryError 堆内存溢出
int[][] arr = new int[1024][1024];
A a = new A();
}
public class Demo {
public static void main(String[] args) {
A a = new A();
System.out.println(a == a.a);
System.out.println(a.a == a.a.a);
}
}
class A {
static A a = new A();
}
编程练习题
public class Demo106 {
public static void main(String[] args) {
Rectangle r1 = new Rectangle();
System.out.println(r1.getArea());
System.out.println(r1.getPerimeter());
Rectangle r2 = new Rectangle(5,10);
System.out.println(r2.getArea());
System.out.println(r2.getPerimeter());
}
}
class Rectangle {
private double width = 1;
private double height = 1;
public Rectangle(){}
public Rectangle(double width,double height) {
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2 * (width + height);
}
}
public class Demo107 {
public static void main(String[] args) {
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 10000000; i++) {
}
sw.stop();
System.out.println(sw.getElapsedTime());
}
}
class StopWatch {
private long startTime;
private long endTime;
public StopWatch() {
startTime = System.currentTimeMillis();
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
endTime = System.currentTimeMillis();
}
public long getElapsedTime() {
return endTime - startTime;
}
public long getStartTime() {
return startTime;
}
public long getEndTime() {
return endTime;
}
}
public class Demo108 {
public static void main(String[] args) {
Fan f1 = new Fan();
System.out.println(f1.toString());
f1.setSpeed(Fan.FAST);
f1.setOn(true);
f1.setColor("red");
f1.setRadius(10);
System.out.println(f1.toString());
}
}
class Fan {
public static final int SLOW = 1;
public static final int MEDIUM = 2;
public static final int FAST = 3;
private int speed = SLOW;
private boolean on = false;
private double radius = 5;
private String color = "blue";
public Fan() {}
public String toString() {
if (on) {
return speed + color + radius;
} else {
return "fan is off" + color + radius;
}
}
public void setSpeed(int speed) {
this.speed = speed;
}
public void setOn(boolean on) {
this.on =on;
}
public void setRadius(double radius) {
this.radius = radius;
}
public void setColor(String color) {
this.color = color;
}
public int getSpeed() {
return speed;
}
public boolean isOn() {
return on;
}
public double getRadius() {
return radius;
}
public String getColor() {
return color;
}
}
public class Demo109 {
public static void main(String[] args) {
RegularPolygon r1 = new RegularPolygon();
System.out.println(r1.getPerimeter());
System.out.println(r1.getArea());
RegularPolygon r2 = new RegularPolygon(6,4);
System.out.println(r2.getPerimeter());
System.out.println(r2.getArea());
RegularPolygon r3 = new RegularPolygon(10,4,5.6,7.8);
System.out.println(r3.getPerimeter());
System.out.println(r3.getArea());
}
}
class RegularPolygon {
private int n = 3;
private double side = 1;
private double x = 0;
private double y = 0;
public RegularPolygon(){}
public RegularPolygon(int n,double side) {
this(n,side,0,0);
}
public RegularPolygon(int n,double side,double x,double y) {
this.n = n;
this.side = side;
this.x = x;
this.y = y;
}
public double getPerimeter() {
return n * side;
}
public double getArea() {
return (n * side * side) / (4 * Math.tan(Math.PI / n));
}
}
public class Demo112 {
public static void main(String[] args) {
Time t1 = new Time();
System.out.println(t1.toString());
Time t2 = new Time(123123123123L);
System.out.println(t2.toString());
Time t3 = new Time(11,6,52);
System.out.println(t3.toString());
t3.setTime(System.currentTimeMillis());
System.out.println(t3.toString());
}
}
class Time {
private long hour;
private long minute;
private long second;
public Time() {
this(System.currentTimeMillis());
}
public Time(long millis) {
hour = cacluHour(millis);
minute = cacluMinte(millis);
second = cacluSecond(millis);
}
public Time(long hour, long minute,long second) {
this.hour = hour;
this.minute = minute;
this.second = second;
}
public void setTime(long elapseTime) {
hour = cacluHour(elapseTime);
minute = cacluMinte(elapseTime);
second = cacluSecond(elapseTime);
}
public String toString() {
return hour + ":" + minute + ":" + second;
}
public long getHour() {
return hour;
}
public long getMinute() {
return minute;
}
public long getSecond() {
return second;
}
private long cacluHour(long millis) {
return millis / 1000 / 60 / 60 % 24;
}
private long cacluMinte(long millis) {
return millis / 1000 / 60 % 60;
}
private long cacluSecond(long millis) {
return millis / 1000 % 60;
}
}
public class Demo113 {
public static void main(String[] args) {
MyInteger m1 = new MyInteger(3);
System.out.println(m1.isEven());
System.out.println(m1.isOdd());
System.out.println(m1.isPrime());
MyInteger m2 = new MyInteger(4);
MyInteger m3 = new MyInteger(13);
System.out.println(MyInteger.isEven(m2));
System.out.println(MyInteger.isPrime(m3));
System.out.println(m2.equals(m3));
System.out.println(MyInteger.parseInt("1234") + 1);
}
}
class MyInteger {
private int value;
public MyInteger(int value) {
this.value = value;
}
public int get() {
return value;
}
public boolean isEven() {
return value % 2 == 0;
}
public boolean isOdd() {
return value % 2 == 1;
}
public boolean isPrime() {
for (int i = 2; i <= value / 2; i++) {
if (value % i == 0) {
return false;
}
}
return true;
}
public static boolean isEven(MyInteger integer) {
return integer.get() % 2 == 0;
}
public static boolean isOdd(MyInteger integer) {
return integer.get() % 2 == 1;
}
public static boolean isPrime(MyInteger integer) {
for (int i = 2; i <= integer.get() / 2; i++) {
if (integer.get() % i == 0) {
return false;
}
}
return true;
}
public boolean equals(int num) {
return value == num;
}
public boolean equals(MyInteger integer) {
return value == integer.get();
}
//"1234"
// i
//4*10^0 + 3*10^1 + 2*10^2 + 1*10^3
public static int parseInt(String str) {
int result = 0;
for (int i = 0; i < str.length(); i++) {
int num = str.charAt(i) - '0';
result = num + result * 10;
}
return result;
}
}
public class Demo114 {
public static void main(String[] args) {
MyPoint p1 = new MyPoint(3,3);
MyPoint p2 = new MyPoint(4,4);
System.out.println(p1.distance(p2));
System.out.println(p1.distance(0,0));
double[] point1 = {1,2};
double[] point2 = {3,4};
double distance = distance(point1,point2);
System.out.println(distance);
}
public static double distance(double[] p1,double[] p2) {
return Math.hypot(p1[0] - p2[0],p1[1] - p2[1]);
}
}
class MyPoint {
private double x;
private double y;
public MyPoint() {
this(0,0);
}
public MyPoint(double x,double y) {
this.x = x;
this.y = y;
}
public double distance(MyPoint point) {
return distance(point.getX(),point.getY());
}
public double distance(double x,double y) {
return Math.hypot(this.x - x , this.y - y);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
}
public class Demo115 {
public static void main(String[] args) {
Queue queue = new Queue();
System.out.println(queue);
for(int i = 1; i <= 10; i++) {
queue.enqueue(i);
}
System.out.println(queue);
for (int i = 1; i <= 6; i++) {
System.out.println(queue.dequeue());
System.out.println(queue);
}
}
}
class Queue {
private int size; //队列中有效元素的个数
private int capacity = 8; //队列容器的最小容量 默认
private int[] element; //队列容器用于存储元素 element.length == size 表示队列已满
public Queue() {
element = new int[capacity];
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public void enqueue(int v) {
if (size == element.length) {
//满了需要扩容
resize(element.length * 2);
}
element[size++] = v;
}
public int dequeue() {
if (isEmpty()) {
return -1; //-1表示一种错误
}
int ret = element[0];
for (int i = 1; i < size; i++) {
element[i - 1] = element[i];
}
size--;
if (size <= element.length / 4 && element.length > capacity) {
//需要缩容
resize(element.length / 2);
}
return ret;
}
private void resize(int newlength) {
int[] newelement = new int[newlength];
for (int i = 0; i < size; i++) {
newelement[i] = element[i];
}
element = newelement;
}
public String toString() { //封装对象的信息 用于打印
String s = "[";
if (isEmpty()) {
s += "]";
} else {
for (int i = 0; i < size; i++) {
if (i == size - 1) {
s = s + element[i] + "]";
} else {
s = s + element[i] + ",";
}
}
}
return s;
}
}
public class Demo117 {
//目前忽略掉的一些问题:数据合法性问题 时间复杂度
public static void main(String[] args) {
char[] chars = {'a','b','c'};
MyString s1 = new MyString(chars);
MyString s2 = new MyString("ab");
System.out.println(s1.compareTo(s2));
MyString s3 = new MyString("ABCD123abcdKKK");
s3.show();
MyString s4 = s3.toLowerCase();
s4.show();
s3.show();
MyString s5 = new MyString("ABC");
MyString s6 = new MyString("abd");
System.out.println(s5.compareToIgnoreCase(s6));
s5.concat(s6).show();
MyString s7 = new MyString("123456");
MyString s8 = new MyString("789");
System.out.println(s7.contains(s8));
MyString s9 = new MyString("xxx.avi");
MyString s10 = new MyString("avi");
System.out.println(s9.endsWith(s10));
MyString s11 = new MyString("abc");
MyString s12 = new MyString("abd");
System.out.println(s11.equals(s12));
MyString s13 = new MyString("abc");
MyString s14 = new MyString("ABC");
System.out.println(s13.equalsIgnoreCase(s14));
MyString s15 = new MyString("123123123");
s15.replace('2','4').show();
System.out.println(s15.startsWith(new MyString("123")));
s15.substring(3,7).show();
}
}
class MyString {
//字符串本身就是一个字符数组 只不过我们不能在该数组中修改元素
private char[] data;
public MyString(char[] chars) {
data = new char[chars.length];
for (int i = 0; i < chars.length; i++) {
data[i] = chars[i];
}
}
public MyString(String s) {
data = new char[s.length()];
for (int i = 0; i < s.length(); i++) {
data[i] = s.charAt(i);
}
}
public MyString(MyString s) {
data = new char[s.length()];
for (int i = 0; i < s.length(); i++) {
data[i] = s.charAt(i);
}
}
public MyString substring(int beginIndex,int endIndex) {
//[begin,end) [1,4)
char[] chars = new char[endIndex - beginIndex];
int index = 0;
/*
123456789
b e
i
*/
for (int i = beginIndex; i < endIndex; i++) {
chars[index++] = data[i];
}
return new MyString(chars);
}
public boolean startsWith(MyString s) {
/*
123456
i
123
j
*/
int i = 0;
int j = 0;
while (true) {
if (charAt(i) == s.charAt(j)) {
i++;
j++;
if (j >= s.length()) {
return true;
}
} else {
return false;
}
}
}
public MyString replace(MyString oldString,MyString newString) {
/*
123123123
23-66
166166166
*/
return null;
}
public MyString replace(char oldChar,char newChar) {
/*
123123123
143143143
2->4
*/
char[] chars = new char[length()];
for (int i = 0; i < length(); i++) {
if (charAt(i) == oldChar) {
chars[i] = newChar;
} else {
chars[i] = data[i];
}
}
return new MyString(chars);
}
public int indexOf(char c) {
for(int i = 0; i < length(); i++) {
if(charAt(i) == c) {
return i;
}
}
return -1;
}
public int indexOf(MyString s) {
//123456
// 45
//->3
return -1;
}
public int lastIndexOf(char c) {
return -1;
}
public int lastIndexOf(MyString s) {
//123456784578
// 45
//->8
return -1;
}
public boolean equalsIgnoreCase(MyString s) {
return compareToIgnoreCase(s) == 0;
}
public boolean equals(MyString s) {
return compareTo(s) == 0;
}
public boolean endsWith(MyString s) {
/*
xxxx.avi
i
avi
j
*/
int i = length() - 1;
int j = s.length() - 1;
while (true) {
if (charAt(i) == s.charAt(j)) {
i--;
j--;
if (j < 0) {
return true;
}
} else {
return false;
}
}
}
public boolean contains(MyString s) {
//KMP算法
/*
i
k1 12335678
j
k2 456
l
*/
char[] k1 = data;
char[] k2 = s.data;
for (int i = 0; i <= k1.length - k2.length; i++) {
if (k1[i] == k2[0]) {
int j = i + 1;
for (int l = 1; l < k2.length; l++,j++) {
if (k1[j] != k2[l]) {
return false;
}
}
return true;
}
}
return false;
}
public MyString concat(MyString s) {
char[] chars = new char[length() + s.length()];
int index = 0;
for (int i = 0; i < length(); i++) {
chars[index++] = data[i];
}
for (int i = 0; i < s.length(); i++) {
chars[index++] = s.charAt(i);
}
return new MyString(chars);
}
public MyString toLowerCase() {
char[] chars = new char[length()];
for (int i = 0; i < data.length; i++) {
char c = data[i];
if (isUpperLetter(c)) {
//'a' 97
//'A' 65
chars[i] = (char)(c + 32);
} else {
chars[i] = c;
}
}
return new MyString(chars);
}
private boolean isUpperLetter(char c) {
return c >= 'A' && c <= 'Z';
}
public MyString toUpperCase(){
return null;
}
public void show() {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
}
System.out.println();
}
public int compareToIgnoreCase(MyString s) {
MyString temp1 = toLowerCase();
MyString temp2 = s.toLowerCase();
return temp1.compareTo(temp2);
}
public int compareTo(MyString s) {
int i = 0;
int j = 0;
while(true) {
if (charAt(i) == s.charAt(j)) {
i++;
j++;
if (i == length() && j == s.length()) {
return 0;
}
if (i < length() && j >= s.length() || i >= length() && j <
s.length()) {
return length() - s.length();
}
} else {
return charAt(i) - s.charAt(j);
}
}
}
public char charAt(int index) {
return data[index];
}
public int length() {
return data.length;
}
}