IDE(集成开发环境)
IDEA的安装使用(自行安装)
Idea常用快捷键
删除当前行:默认Ctrl+Y 修改为Ctrl + D
复制当前行到上一行:默认Ctrl + D 修改为 Ctrl + Alt + 向下箭头
补全代码:Alt + /
添加注释或取消注释:Ctrl + /
导入该行需要的类:Alt + Enter
快速格式化代码:Ctrl + Alt + L
快速运行程序:默认Shift + F10 可修改Alt +R
生成构造器等:Alt + Insert(提高开发效率)
查看一个类的层级关系:crtl + H(学习继承后非常有用)
定位到方法:Ctrl + B
自动分配变量名:通过后面加.var
模板快捷键
main: public static void main...
sout: System.out.println...
fori: for(int i = 0)...
包
作用:
区分相同名字的类
类很多是可以很好的管理类
控制访问范围
package xx.xxx;
package: 关键字,表示打包
xx.xxx: 表示包名
包的本质就是创建不同的文件夹/目录保存类文件
命名规则
只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是保留字或关键字
一般是小写字母+小圆点
一般是com.公司名.项目名.业务模块名
java中常用的包
java.lang.*//lang包是基本包,默认引入,不需要再引入
java.util.*//util包,系统提供的工具包,工具类,使用Scanner
java.net.*//网络包,网络开发
java.awt.*//是做java的界面开发,GUI
import之类在package和类定义之间
访问修饰符
java提供4种访问修饰符号,用于控制方法和属性的访问权限
公开级别:public修饰,对外公开
受保护级别:protected修饰,对子类和同一个包中的类公开
默认级别:没有修饰符号,向同一个包的类公开
私有级别:private修饰,只有类本身可以访问,不对外公开
访问级别 | 访问控制修饰符 | 同类 | 同包 | 子类 | 不同包 |
---|---|---|---|---|---|
公开 | public | √ | √ | √ | √ |
受保护 | protected | √ | √ | √ | × |
默认 | 没有修饰符 | √ | √ | × | × |
私有 | private | √ | × | × | × |
可以修饰属性、方法和类,只有默认和public才能修饰类
面向对象的三大特征:封装 继承 多态
封装(encapsulation)
封装就是把抽象出来的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作
隐藏实现细节
可以对数据进行验证,保证安全合理
封装实现步骤:
1. 将属性进行私有化private,不能直接修改属性
2. 提供一个公共的(public)set方法,用于对属性判断并赋值
3. 提供一个公共的(public)get方法,用于获取属性的值
简单案例
package com.lemon.encap;
public class Encapsulation01 {
public static void main(String[] args) {
// Person person = new Person();
Person person = new Person("tom",28,20000);
// person.setName("jack");
// person.setAge(30);
// person.setSalary(20000);
System.out.println(person.info());
}
}
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;
//可以将set方法写在构造器中
setName(name);
setAge(age);
setSalary(salary);
}
public String getName() {
return name;
}
public void setName(String name) {
if(name.length() >= 2 && name.length() <=6) {
this.name = name;
} else {
System.out.println("名字输入的长度不对,需要(2~6)个字符,默认名字");
this.name = "无名人";
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 1 && age <= 120) {
this.age = age;
} else {
System.out.println("你设置的年龄不对,需要在(1~120),给默认年龄18");
this.age = 18;
}
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//写一个方法,返回属性信息
public String info() {
return "信息为 name=" + name + " age=" + age + " salary=" + salary;
}
}
继承(Extends)
继承可以解决代码复用。
代码的扩展性和维护性提高。
当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有子类不需要重新定义这些变量和方法,只需要通过extends来声明继承父类即可。
继承基本语法
class 子类 extends 父类 {}
1. 子类就会自动拥有父类的属性和方法
2. 父类有叫超类 基类
3. 子类又叫派生类
细节
1. 子类继承了所以的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能在子类直接访问,要通过父类提供公共的方法去访问
2. 子类必须调用父类的构造器,完成父类的初始化
3. 当创建子类对象时,不管使用那个子类的构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类构造器中用super去指定使用父类的哪个构造器完成父类的初始化操作,否则编译不会通过
4. 如果希望指定去调用父类的某个构造器,则显示的调用一下:super(参数列表)
5. super在使用时,必须放在构造器第一行(super只能在构造器中使用)
6. super()和this()都只能在构造器第一行,因此这两个方法不能共存在一个构造器
7. java所有类都是Object类的子类,Object是是所有类的基类
8. 父类构造器的调用不限于直接父类,将一直向上追溯到Object类(顶级父类)
9. 子类最多只能继承一个父类(指直接继承),即java是单继承机制
10. 不能滥用继承,子类和父类之间必须满足is-a的逻辑关系
继承的本质分析
按查找关系来返回信息(子类->父类->父类的父类...)
package com.lemon.extend_;
public class ExtendsTheory {
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.name);//大头儿子
System.out.println(son.age);//39
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代表父类的引用,用于访问父类的属性、方法、构造器
1. 访问父类的属性,但不能访问父类的private属性 super.属性名
2. 访问父类的方法,但不能访问父类的private方法 super.方法名(参数列表)
3. 访问父类的构造器 super(参数列表) 只能放在构造器第一句,只能出现一句
作用
1. 分工明确,父类属性由父类初始化,子类属性由子类初始化
2. 当子类和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
xx()和this.xx()一致
super.xx()从父类开始找
1. 先找本类,如果有,则调用
2. 如果没有,则找父类(如果有调用)
3. 如果父类没有,则找父类的父类,直到Object类
找到了不能访问:cannot access
没找到:方法/属性不存在
3. super的访问不限于直接父类,如果爷爷类和本类中有同样的成员,也可以使用super去访问爷爷类的成员,如果多个基类(上级类)中都有同名的成员,使用super就遵循就近原则
区别点 | this | super |
---|---|---|
访问属性 | 访问本类中的属性,如果本类中没有属性则从父类中继续查找 | 从父类开始查找属性 |
调用方法 | 访问本类中的方法,如果本类中没有方法则从父类中继续查找 | 从父类开始查找方法 |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
特殊 | 表示当前对象 | 子类中访问父类对象 |
方法重写/覆盖(Override)
方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么就说子类的这个方法覆盖了父类的方法
1. 子类方法的参数、方法名称要和父类方法的参数、方法名完全一致
2. 子类方法的返回类型和父类方法的返回类型一样,或者是父类返回类型的子类
(父类返回Object,子类返回String)
3. 子类方法不能缩小父类方法的访问权限
多态(Polymorphic)
方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承基础之上的
方法的多态
重写或重载体现多态
对象的多态
1. 一个对象的编译类型和运行类型可以不一致
2. 编译类型在定义对象时,就确定了,不能改变
3. 运行类型是可以变化的
4. 编译类型看定义时 = 号的左边,运行类型 = 号的右边
Animal animal = new Dog(); animal编译类型是Animal,运行类型是Dog
animal = new Cat(); animal运行类型变成了Cat,编译类型仍然是Animal
多态的前提是:两个对象(类)存在继承关系
多态的向上转型:
本质:父类的引用指向了子类的对象
语法:父类类型 引用名 = new 子类类型()
特点:编译类型看左边 运行类型看右边
可以调用父类中的所有成员(需遵守访问权限)
不能调用子类中的特有成员
最终运行结果看子类的具体实现
package com.lemon.poly_.detail;
public class PolyDetail {
public static void main(String[] args) {
//向上转型:父类的引用指向子类对象
//编译类型 Animal 运行类型 Cat
Animal animal = new Cat();
//Object abj = new Cat();//可以 Object也是 Cat 的父类
//向下转型
//编译类型 Cat 运行类型 Cat
Cat cat = (Cat)animal;
cat.catchMouse();
}
}
public class Animal {
String name = "动物";
int age = 10;
public void sleep() {
System.out.println("睡");
}
public void run() {
System.out.println("跑");
}
public void eat() {
System.out.println("吃");
}
public void show() {
System.out.println("hello,你好");
}
}
public class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
多态向下转型:
语法:子类类型 引用名 = (子类类型)父类引用
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后,就可以调用子类类型的所有成员
属性先看编译类型,通过后结果看运行类型!!!
方法看运行类型!!!
instanceOf比较操作符
用于判断对象的运行类型是否为XX类型或者XX类型的子类型
xx instanceOf XX
=======================================================================
头晕眼花的一天!!!