IDE编程
常用快捷键
- 删除当前行,默认是ctrl+Y自己配置ctrl+ d
- 复制当前行,自己配置ctrl + alt+向下光标
- 补全代码alt+/
- 添加注释和取消注释ctrl+/【第一次是添加注释,第二次是取消注释】
- 导入该行需要的类先配置auto import ,然后使用alt+enter即可
- 快速格式化代码ctrl +alt + L
- 快速运行程序自己定义alt+R
- 生成构造器等alt + insert[提高开发效率]
- 查看一个类的层级关系 ctrl+H[学习继承后,非常有用]
- 将光标放在一个方法上,输入 ctrl+B,可以定位到方法[学继承后,非常有用]
- 自动的分配变量名,通过在后面假.var[老师最喜欢的]
还有很多其它的快捷键...
包
基本语法
package 关键字,表示打包
包的本质是不同的文件夹/目录来保存文件
常用的包
一个包下,包含很多的类,java 中常用的包有:
- java.lang.* //lang 包是基本包,默认引入,不需要再引入.
- java.util.* //util 包,系统提供的工具包, 工具类,使用 Scanner
- java.net.* //网络包,网络开发
- java.awt.* //是做 java 的界面开发,GUI
引入包 import 包名;
- package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有
一句package - import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求。
访问修饰符
java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):
公开级别:用 public 修饰,对外公开
受保护级别:用 protected 修饰,对子类和同一个包中的类公开
重点:
受保护的访问修饰符-protected
protected 需要从以下两个点来分析说明:
子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。
// 示例一
package p1;
public class Father1 {
protected void f() {
} // 父类Father1中的protected方法
}
package p1;
public class Son1 extends Father1 {
}
package p2;
public class Son2 extends Father1{
}
package p1;
public class Test {
public static void main(String[] args) {
Son1 son1 = new Son1();
son1.f(); // Compile OK ----(1)
son1.clone(); // Compile Error ----(2)
Son2 son = new Son2();
son2.f(); // Compile OK ----(3)
son2.clone(); // Compile Error ----(4)
Test t = new Test();
t.clone; // Compile OK
// 测试类test只可以使用test类的继承Object类而来的test.clone()方法
}
}
protected详解链接:https://blog.csdn.net/qq_37424916/article/details/107371305
默认级别:没有修饰符号,向同一个包的类公开.
私有级别:用 private 修饰,只有类本身可以访问,不对外公开
面向对象编程三大特征:封装
封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
1)隐藏实现细节:方法(连接数据库)<--调用(传入参数..)2)可以对数据进行验证,保证安全合理
封装的步骤:
将属性进行私有化private【不能直接修改属性】
提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型参数名)V/Xxx表示某个属性
//加入数据验证的业务逻辑
属性=参数名;
}
提供一个公共的(public)get方法,用于获取属性的值
public数据类型getXxx(){//权限判断,Xx某个属性
return xx;
}
将构造器和 setXxx 结合
看一个案例
//有三个属性的构造器
public Person(String name, int age, double salary) {
// this.name = name;
// this.age = age;
// this.salary = salary;
//我们可以将 set 方法写在构造器中,这样仍然可以验证
setName(name);
setAge(age);
setSalary(salary);
}
继承:
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可。画出继承的示意图
继承的基本语法:
class子类extends父类{}
1)子类就会自动拥有父类定义的属性和方法2)父类又叫超类,基类。
3)子类又叫派生类。
代码的复用性提高了
代码的扩展性和维护性提高了
继承的细节
- 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
- 子类必须调用父类的构造器, 完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译 不会通过(怎么理解。) [举例说明]
- 如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
- super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
- super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
- java 所有类都是 Object 类的子类, Object 是所有类的基类.
- 父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)
- 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。 思考:如何让 A 类继承 B 类和 C 类? 【A 继承 B, B 继承 C】 接口可以多继承
- 不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
继承的本质
//(1) 首先看子类是否有该属性
//(2) 如果子类有这个属性,并且可以访问,则返回信息
//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到 Object...
super关键字
super 代表父类的引用,用于访问父类的属性、方法、构造器
基本语法:
1.访问父类的属性,但不能访问父类的private属性[案例]
super.属性名;
2.访问父类的方法,不能访问父类的private方法
super.方法名(参数列表);
3.访问父类的构造器(这点前面用过):
super(参数列表);只能放在构造器的第一句,只能出现一句!
super和this的比较
方法重写/覆盖(override)
简单的说:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法
多态:
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
多态的表现:1.方法的多态:重写和重载就体现多态
2.对象的多态
(1)一个对象的编译类型和运行类型可以不一致
(2)编译类型在定义对象时,就确定了,不能改变
(3)运行类型是可以变化的.
(4)编译类型看定义时=号的左边,运行类型看=号的右边
多态细节
多态的前提是:两个对象(类)存在继承的关系
java 的动态绑定机制(非常非常重要.)
多态的应用
多态数组 PloyArray.java 数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个Teacher 对象, 统一放在数组中,并调用每个对象 say 方法. 应用实例升级:如何调用子类特有的方法,比如 Teacher 有一个 teach , Student 有一个 study
public class PloyArray {
public static void main(String[] args) {
//应用实例:现有一个继承结构如下:要求创建 1 个 Person 对象、
// 2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组中,并调用每个对象 say 方法Person[] persons = new Person[5];
persons[0] = new Person("jack", 20);
persons[1] = new Student("mary", 18, 100);
persons[2] = new Student("smith", 19, 30.1);
persons[3] = new Teacher("scott", 30, 20000);
persons[4] = new Teacher("king", 50, 25000);
//循环遍历多态数组,调用 say
for (int i = 0; i < persons.length; i++) {
//提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有 JVM 来判断System.out.println(persons[i].say());//动态绑定机制
//这里大家聪明. 使用 类型判断 + 向下转型. if(persons[i] instanceof Student) {//判断 person[i] 的运行类型是不是 Student
Student student = (Student)persons[i];//向下转型
student.study();
//小伙伴也可以使用一条语句 ((Student)persons[i]).study();
} else if(persons[i] instanceof Teacher) {
Teacher teacher = (Teacher)persons[i];
teacher.teach();
} else if(persons[i] instanceof Person){
//System.out.println("你的类型有误, 请自己检查...");
} else {
System.out.println("你的类型有误, 请自己检查...");
}
}
}
}
多态参数
方法定义的形参类型为父类类型,实参类型允许为子类类型
public class PloyParameter {
public static void main(String[] args) {
Worker tom = new Worker("tom", 2500);
Manager milan = new Manager("milan", 5000, 200000);
PloyParameter ployParameter = new PloyParameter();
ployParameter.showEmpAnnual(tom);
ployParameter.showEmpAnnual(milan);
ployParameter.testWork(tom);
ployParameter.testWork(milan);
}
//showEmpAnnual(Employee e)
//实现获取任何员工对象的年工资,并在 main 方法中调用该方法 [e.getAnnual()]
public void showEmpAnnual(Employee e) {
System.out.println(e.getAnnual());//动态绑定机制. }
//添加一个方法,testWork,如果是普通员工,则调用 work 方法,如果是经理,则调用manage 方法public void testWork(Employee e) {
if(e instanceof Worker) {
((Worker) e).work();//有向下转型操作
} else if(e instanceof Manager) {
((Manager) e).manage();//有向下转型操作
} else {
System.out.println("不做处理...");
}
}
}
object类
equals
hashCode方法
提高具有哈希结构的容器的效率!
两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
两个引用,如果指向的是不同对象,则哈希值是不一样的
哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。
案例演示[HashCode_.java]: obj.hashCode() [测试:A obj1 = new A(); A obj2 = new A(); A obj3 = obj1]
后面在集合,中 hashCode 如果需要的话,也会重写, 在讲解集合时,说如何重写hashCode()
toString方法
基本介绍 默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】 子类往往重写 toString 方法,用于返回对象的属性信息
重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式.
案例演示:Monster [name, job, sal] 案例: ToString_.java
当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster);就会默认调用monster.toString()
finalize方法(垃圾回收机制)
I)当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作【演示】
2)什么时候被回收:当某个对象没有任何引用时,则jyvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法。
3)垃圾回收机制的调用,是由系统来决定(即有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制,
DEBUG调试
1.在开发中,新手程序员在查找错误时,这时老程序员就会温馨提示,可以用断点调试,
一步一步的看源码执行的过程,从而发现错误所在。
2.重要提示:在断点调试过程中,是运行状态,是以对象的运行类型来执行的.A extends B; Bb = new AO; b.xx();
1.断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,
然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个Bug
2.断点调试是程序员必须掌握的技能。
3.断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的Java水平。
F7(跳入)F8(跳过)
shift+F8(跳出)F9(resume,执行到下一个断点)
F7:跳入方法内
F8:逐行执行代码.shift+F8:跳出方法