笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html)
●IDEA介绍(内容仅需了解)
●Eclipse介绍
IDEA的安装
官网:https://www.jetbrains.com/ IDEA下载后,就可以开始安装。
本人笔记中使用的 IDEA 2020.2
IDEA的基本介绍和使用
使用IDEA创建Java项目(project),看看IDEA是如何使用的,IDEA 是以项目的概念,来管理我们的java源码的
IDEA常用快捷键
●模板/自定义模板
file -> settings -> editor-> Live templates ->
查看有哪些模板快捷键/可以自己增加模板
public class TestTemplate {
//main就是一个模板的快捷键.
public static void main(String[] args) {
//sout模板快捷键
System.out.println("hello ,world");
//foni模板快捷键
for (int i = o; i <; i++) {
}
}
}
●看一个应用场景
现在有两个程序员共同开发一个java项目,程序员xiaoming希望定义一个类取名Dog ,程序员xiaoqiang也想定义一个类也叫 Dog。两个程序员为此还吵了起来,怎么办?
●包的三大作用
●包基本语法
package com.hspedu;
●说明:
●包的本质分析(原理)
包的本质实际上就是创建不同的文件夹来保存类文件。
//当出现多个包中的同class需要在同一个java文件中调用时
package com.use;
import com.xiaoqiang. Dog;
public class Test {
public static void main(String[] args){
Dog dog = new Dog();
System.out.println(dog) ;//com.xiaoqiang. Dog@1540e19d
com.xiaoming.Dog dog1 = new com.xiaoming.Dog();
System.out.println(dog1);//com.xiaoming. Dog@677327b6
}
}
●包的命名
✔命名规则:
只能包含数字、字母、下划线、小圆点.,但不能用数字开头,不能是关键字或保留字
✔命名规范
一般是小写字母+小圆点一般是
com.公司名.项目名.业务模块名
比如:com.hspedu.oa.model; com.hspedu.oa.controller;
举例:
com.sina.crm.user //用户模块
com.sina.crm.order //订单模块
com.sina.crm.utils //工具类
●常用的包
一个包下,包含很多的类,java中常用的包有:
java.lang.* //lang包是基本包,默认引入,不需要再引入.
java.util.* //util 包,系统提供的工具包,工具类,使用Scanner
java.net.* //网络包,网络开发
java.awt.* //是做java的界面开发,GUI
●如何引入包
com.hspedu.pkg : Import01.java
语法: import 包;
我们引入一个包的主要目的是要使用该包下的类
比如import java.util.Scanner;就只是引入一个类Scanner
import java.util.*;//表示将java.util包所有都引入
案例:使用系统提供 Arrays完成数组排序
●注意事项和使用细节
基本介绍
java提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):
4种访问修饰符的访问范围
| 访问级别 | 修饰符 | 当前类 | 同一包内 | 子类(不同包) | 其他包 |
|---|---|---|---|---|---|
| 公开 | public |
Y | Y | Y | Y |
| 受保护 | protected |
Y | Y | Y | N |
| 默认 | 无 | Y | Y | N | N |
| 私有 | private |
Y | N | N | N |
●使用的注意事项
面向对象编程三大特征
基本介绍
面向对象编程有三大特征:封装、继承和多态。
封装介绍
封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
封装的理解和好处
封装的实现步骤
将属性进行私有化private【不能直接修改属性】
提供一个公共的set方法,用于对属性判断并赋值
public void setXxx(类型参数名){
//加入数据验证的业务逻辑(判断数据是否合理)
属性=参数名;
}
提供一个公共的get方法,用于获取属性的值
public XX getXxx(){//权限判断
return xx;
}
●快速入门案例
看一个案例
那么在java中如何实现这种类似的控制呢?
请大家看一个小程序,不能随便查看人的年龄,工资等隐私,并对设置的年龄进行合理的验证。年龄合理就设置,否则给默认年龄,必须在1-120,年龄,工资不能直接查看,name的长度在2-6字符之间
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(126);
System.out.println(person.getAge());
}
}
class Person {
public String name;
private int age;
private double salary;
//alt+insert ,再选Getter and Setter,选择需要创建的
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < 120 && age > 0) {
this.age = age;
} else {
System.out.println("年龄范围错误,默认设置18");
this.age = 18;
}
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
●将构造器和setXxx结合
public class Test {
public static void main(String[] args) {
......
}
}
class Person {
public String name;
private int age;
private double salary;
public Person() {
}
public Person(String name, int age, double salary) {
//this.name = name;
//this.age = age;
//this.salary = salary;
setName(name);
setAge(age);
setSalary(salary);
}
......
}
●为什么需要继承
我们编写了两个类,一个是Pupil类(小学生),一个是Graduate(研究生).问题:两个类的属性和方法有很多是相同的,怎么办?
●继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。
画出继承的示意图
●继承的基本语法
class 子类 extends 父类{
}

class 父类 {
//共有属性
public String name;
public int age;
private double score;//成绩//共有的方法
public void setScore(double score) {
this.score = score;
}
}
class 子类 extends 父类 {
public void teting() {
System.out.println("小学生" +name + "正在考小学数学..");
}
}
●继承的深入讨论/细节问题
●继承的本质分析(内存分析)(重要)
√案例
我们看一个案例来分析当子类继承父类,创建子类对象时,内存中到底发生了什么?
提示:当子类对象创建好后,建立查找的关系
public class ArrayTest {
public static void main(String[] args) {
Son son = new Son();//内存的布局
//?->这时请大家注意,要按照查找关系来返回信息
//(1)首先看子类是否有该属性
//(2)如果子类有这个属性,并且可以访问,则返回信息
//(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
//(4〕如果父类没有就按照(3)的规则,继续找上级父类,直到0bject...
System.out.println(son.name);
System.out.println(son.hobby);
}
}
class GrandPa {
String name = "大头爷爷";
String hobby = "旅游";
}
class Father extends GrandPa {//父类
String name = "大头爸爸";
int age = 39;
}
class Son extends Father {//子类
String name = "大头儿子";
}

基本介绍
super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法
super给编程带来的便利/细节
super和this的比较
| 区别点 | this | super |
|---|---|---|
| 访问属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找 | 从父类开始查找属性 |
| 调用方法 | 访问本类中的方法,如果本类没有此方法则从父类继续查找. | 从父类开始查找方法 |
| 调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
| 特殊 | 表示当前对象 | 子类中访问父类对象 |
基本介绍
简单的说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
注意事项和使用细节
方法重写也叫方法覆盖,需要满足下面的条件
重写和重载比较
| 名称 | 发生范围 | 方法 | 形参列表 | 返回类型 | 修饰符 |
|---|---|---|---|---|---|
| 重载(overload) | 本类 | 必须一样 | 类型,个数或者顺序至少有一个不同 | 无要求 | 无要求 |
| 重写(override) | 父子类 | 必须一样 | 相同 | 子类重写的方法,返回的类型和父类返回的类型一致,或者是其子类 | 子类方法不能缩小父类方法的访问范围 |
先看一个问题
问题描述:请编写一个程序,Master类中有一个 feed(喂食)方法,可以完成主人给动物喂食物的信息。


传统的方法带来的问题是什么?如何解决?
问题是:每次都要创建新的方法存放动物种类。代码的复用性不高,而且不利于代码维护
解决方案:引出我们要讲解的多态
多[多种]态[状态]基本介绍
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
多态的具体体现
方法的多态
重写和重载就体现多态
对象的多态(核心,困难,重点)老韩重要的几句话(记住):
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的.
(4)编译类型看定义时=号的左边,运行类型看=号的右边
案例:
Animal animal = new Dog();【animal编译类型是Animal,运行类型Dog】
animal = new Cat();【animal的运行类型变成了Cat,编译类型仍然是Animal】
一个父类的对象引用可以指向其子类对象
多态快速入门案例
使用多态的机制来解决主人喂食物的问题,走代码。
传入的实参是 cat和fish,对应形参可以为animal和food

多态注意事项和细节讨论
✔多态的前提是:两个对象(类)存在线承关系
✔多态的向上转型
向上转型调用方法的规则如下:
可以调用父类中的所有成员(需遵守访问权限)
但是不能调用子类的特有的成员
因为在编译阶段,能调用哪些成员,是由编译类型来决定的
最终运行效果看子类(运行类型)的具体实现,即调用方法时,按照从子类(运行类型)开始查找方法
然后调用,规则我前面我们讲的方法调用规则一致。
多态注意事项和细节讨论
多态的向下转型
语法:子类类型 引用名 = (子类类型) 父类引用;【例:Cat cat=(Cat) animal】
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
可以调用子类类型中所有的成员
多态注意事项和细节
属性没有重写之说!属性的值看编译类型(运行调用属性时认准编译类型,在方法中调用属性则是调用该方法所在类中的属性)
instanceof比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型
packapublic class Poly2 {
public static void main(String[] args) {
Base base=new Sub();
base.Aa();//111111
System.out.println(base.count);//10
Sub sub=(Sub) base;
System.out.println(sub.count);//20
System.out.println(base instanceof Base);//true
System.out.println(base instanceof Sub);//true
Object obj = new Object();
System.out.println(obj instanceof Base); //false
}
}
class Base {//父类
int count = 10;//属性
public void Aa(){
System.out.println("00000");
}
}
class Sub extends Base {//子类
int count = 20;//属性
public void Aa(){
System.out.println("111111");
}
}
java的动态绑定机制(非常非常重要.)
多态的应用
equals方法
"==" 和 "equals" 的对比[面试题]
hashCode方法
toString方法
基本介绍
finalize方法
提示:我们在实际开发中,几乎不会运用finalize,所以更多就是为了应付面试.
一个实际需求
断点调试介绍
断点调试的快捷键:
F7(跳入) F8(跳过) shift+F8(跳出) F9(resume,执行到下一个断点)
F7:跳入方法内
F8:逐行执行代码.
shift+F8:跳出方法

小技巧:将光标放在某个变量上,可以看到最新的数据。
Alt+Shift+F7强制跳入(可以用来看数据在源码中的情况)
项目需求说明
使用Java 开发零钱通项目,可以完成收益入账,消费,查看明细,退出系统等功能.
项目界面

项目的界面
化繁为简.
先完成显示菜单,并可以选择
import java.util.Scanner;
public class SmallChangeSys {
public static void main(String[] args) {
boolean loop=true;
Scanner scanner = new Scanner(System.in);
String key="";
do {
System.out.println("==========零钱通菜单===========");
System.out.println("\t\t1 零钱通明细");
System.out.println("\t\t2 收益入账");
System.out.println("\t\t3 消费");
System.out.println("\t\t4 退 出");
System.out.println("请选择(1-4):");
key=scanner.next();
switch (key){
case "1":
System.out.println("1 零钱通");
break;
case "2":
System.out.println("2 收益入账");
break;
case "3":
System.out.println("3 消费");
break;
case "4":
System.out.println("4 退 出");
loop=false;
break;
default:
System.out.println("选择有误");
}
}while (loop);
System.out.println("---退出了零钱通---");
}
}
完成零钱通明细
完成收益入账
完成消费
完成退出功能
加入简单的逻辑判断
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class SmallChangeSys {
public static void main(String[] args) {
boolean loop = true;
Scanner scanner = new Scanner(System.in);
String key = "";
String details = "----------------零钱通明细------------------";
//3.完成收益入账完成功能驱动程序员增加新的变化和代码/老韩思路,定义新的变量
double money = 0;
double balance = 0;
Date date = null; // date 是 java.util.Date类型,表示日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的
String note = "";
do {
System.out.println("\n==========零钱通菜单===========");
System.out.println("\t\t1 零钱通明细");
System.out.println("\t\t2 收益入账");
System.out.println("\t\t3 消费");
System.out.println("\t\t4 退 出");
System.out.println("请选择(1-4):");
key = scanner.next();
switch (key) {
case "1":
System.out.println(details);
break;
case "2":
System.out.print("收益入账金额:");
money = scanner.nextDouble();// money的值范围应该校验-》一会在完善
if (money <= 0) {
System.out.printf("收益入账金额需要大于0");
break;
}
balance += money;
//拼接收益入账信息到details
date = new Date();//获取当前日期
details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t" + balance;
break;
case "3":
System.out.println("3 消费");
System.out.println("消费金额:");
money = scanner.nextDouble();
if (money <= 0 || money > balance) {
System.out.printf("消费金额应该在0-" + balance + "范围内");
}
//money 的值范围应该校验-》一会在完善
System.out.print("消费说明:");
note = scanner.next();
balance -= money;
//拼接消费信息到details
date = new Date();//获取当前日期
details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
break;
case "4":
String choice = "";
while (true) {
System.out.printf("确定退出?y/n");
choice = scanner.next();
if ("y".equals(choice) || "n".equals(choice)) {
break;
}
}
if (choice.equals("y")) {
loop = false;
}
break;
default:
System.out.println("选择有误");
}
} while (loop);
System.out.println("---退出了零钱通---");
}
}
再将程序改成OOP版本,自行体会OOP编程带来的好处(将各个功能封装到不同方法)
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class SmallChangeSysOOP {
boolean loop = true;
Scanner scanner = new Scanner(System.in);
String key = "";
String details = "----------------零钱通明细------------------";
//3.完成收益入账完成功能驱动程序员增加新的变化和代码/老韩思路,定义新的变量
double money = 0;
double balance = 0;
Date date = null; // date 是 java.util.Date类型,表示日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");//可以用于日期格式化的
String note = "";
//先完成显示菜单,并可以选择
public void mainMenu() {
do {
System.out.println("\n==========零钱通菜单===========");
System.out.println("\t\t1 零钱通明细");
System.out.println("\t\t2 收益入账");
System.out.println("\t\t3 消费");
System.out.println("\t\t4 退 出");
System.out.println("请选择(1-4):");
key = scanner.next();
switch (key) {
case "1":
this.detail();
break;
case "2":
this.income();
break;
case "3":
this.pay();
break;
case "4":
this.exit();
break;
default:
System.out.println("选择有误");
}
} while (loop);
}
//完成零钱通明细
public void detail() {
System.out.println(details);
}
public void income(){
System.out.print("收益入账金额:");
money = scanner.nextDouble();// money的值范围应该校验-》一会在完善
if (money <= 0) {
System.out.printf("收益入账金额需要大于0");
return;
}
balance += money;
//拼接收益入账信息到details
date = new Date();//获取当前日期
details += "\n收益入账\t+" + money + "\t" + sdf.format(date) + "\t" + balance;
}
public void pay(){
System.out.println("3 消费");
System.out.println("消费金额:");
money = scanner.nextDouble();
if (money <= 0 || money > balance) {
System.out.printf("消费金额应该在0-" + balance + "范围内");
}
//money 的值范围应该校验-》一会在完善
System.out.print("消费说明:");
note = scanner.next();
balance -= money;
//拼接消费信息到details
date = new Date();//获取当前日期
details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t" + balance;
}
public void exit(){
String choice = "";
while (true) {
System.out.printf("确定退出?y/n");
choice = scanner.next();
if ("y".equals(choice) || "n".equals(choice)) {
break;
}
}
if (choice.equals("y")) {
loop = false;
}
}
}
class SmallChangeSysApp{
public static void main(String[] args) {
SmallChangeSysOOP smallChangeSysOOP = new SmallChangeSysOOP();
smallChangeSysOOP.mainMenu();
}
}
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的rubyyaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir
假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。