JAVA基础和进阶(记录到继承)
毕业以后没有进入编程行业,现在想要重新学习一下基础尽早转行,记录一下一些细节方便自己回忆复习
-
java语言的5.0是重大更新的版本,8.0是公司中较多使用的版本
-
Java之所以能够实现跨平台运行,使用了JVM(Java虚拟机),给不同操作系统提供不同的虚拟机即可实现跨平台运行
-
JRE(Java runtime environment),包含了JVM和运行时所需的核心类库
-
JDK(Java development kit),包含了JRE和Javac.exe(编译工具)和java.exe(运行工具)
-
通过官方网站 www.oracle.com 获取jdk
-
常用命令行cd …回退一层 cd \回退到根目录 dir显示文件夹内文件 cls清屏命令行 exit退出命令窗口
-
为了方便使用javac和java这两个工具,才要配置环境变量
JAVA_HOME (jdk实际安装路径) C:\Program Files\Java\jdk1.8.0_181 CLASSPATH %JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar PATH %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin 配置完成后 win+R,输入cmd打开命令行提示符窗口,输入java-version查看是否配置正确注意如果安装多个jdk可能会出现java版本和javac版本不一致导致命令行中运行java文件失败
-
命令行窗口中按下Tab键可以进行自动补齐
-
Java中的关键字: 关键字字母全部小写
-
整数相除只能得到整数,想要得到小数,必须有浮点数参与计算 /取结果的商,%取余得到除法的余数 371 / 100 = 3 371 %
100 = 71 -
数据类型等级顺序:byte,short,char->int->long->float->double
所以不同类型在一起运算时,低等级会被自动提升为高等级 有些需要强制转换类型的时候,long类型直接”12L”就可以了 -
+=这种操作(-= /=。。。。。。)中隐含了强制类型转换 short i =0; I += 20;
这个表达式等价于 I = I + 20;但是i是short类型的,+20会将其类型改变为int类型,但是他本身是short类型,因此会报错。所以需要一个强制类型转换I = (short) I + 20; -
三元运算符的格式和结果: 关系表达式?表达式1:表达式2 a>b ? a :b
先计算关系表达式,结果为true,表达式1的结果为计算结果,结果为false,表达式二的结果为计算结果 -
case穿透:
swithc语句中的case如果不写break;,就会穿透到下一个case直到遇到有break的case。多条件符合统一结果时可以这么写。 -
for循环的死循环格式:for(;😉
IDEA快捷键
快捷键 | 内容 |
---|---|
psvm | 快速生成main方法 public static void main(String [] args){} 作为程序的入口 |
sout | 快速生成输出语句 System.out.println() |
ctrl+alt+space | 快速补全命令 |
ctrl+shift+o | 快速导包 |
ctrl+enter | 自动导包 |
ctrl+/ | 选中的代码单行注释,重复一次取消 |
ctrl+shift+/ | 选中的代码多行注释,重复一次取消 |
ctrl+alt+l | 自动对齐代码换行 |
ctrl+alt+v | 自动生成方法返回值类型的一个对象 |
将内容选中后按下TAB | 多行保留格式同时TAB(向右缩进) |
将内容选中后按下shift+TAB | 多行保留格式同时向左缩进) |
ctrl+f | 搜索房当前文件中代码出现位置 |
对选中部分按下ctrl+b | 进入到该方法中去 |
Alt+7(View->Tool Windows->Structure) | 打开一个窗口,展示类的所有信息,方便快速找到对的方法等 |
-
栈内存和堆内存:
栈内存:存储局部变量,使用完毕立即消失,主程序和各种方法调用都在这里加载
堆内存:存储new出来的对象、实体,会有一个地址值用来存储,空闲时回收器回收,用于存出各种创建的变量和对象等信息 -
超出范围的名词叫做“索引越界”
方法在传参的时候也可以写fangfa(a:10,b:20);
不需要自己写,是IDEA自动生成的a:方便查看调用的方法中的参数名 -
方法重载:多个方法在同一个类中,同名但是参数不同,与返回值无关
-
形参和实参,如果传递的参数不是引用类型,就只传了个数据过去,在方法中对形参的修改不会对实参造成任何影响。但是如果传递的参数是引用类型,比如说ArrayList集合这种,传递了实参的地址这种,那么对形参的修改也就相当于对实参的修改。
-
System.out.println和System.out.print的区别:带ln的每次输出之后会换行
-
Debug查看时如果遇到需要键盘输入的地方,就需要先输入之后才能继续Debug
-
For循环中可以定义多个变量,多个自增自减 ,中间使用,隔开
for(int i =0 , j=arr.length-1; i>=0 && j>0;i++,j--){
System.out.println(i+""+j); }
- Java中没有foreach关键字,但是可以使用
for(数据类型 变量名:遍历对象名)
int [] testArr = {1,2,1,3,5};
for(int i : testArr){
sout;
}
这样的格式来使用增强for循环(jdk6之后才支持)
- 类和对象: 类中保存对象的成员变量和成员方法,成员方法就不用写static创建对象和创建数组本质一样,所以他们都是存储在堆内存中,主程序在栈内存中调用对象的方法时,对象将方法加载到栈内存中,该方法使用完毕后自动从栈内存中消失
- 成员变量和局部变量的区别:
成员变量:定义在类中,方法外,存储在堆内存,随着对象存在而存在
局部变量:定义在方法内部,存储在栈内存,随着方法调用存在而存在
public class MarioDemo{
//成员变量
String name = "";
public static void main(String [] args){
//局部变量
int age = 0;
}
}
- 构造方法:用来创建对象并对某些成员变量进行初始化 格式: publc 类名(“可以有参数也可以没有”){}
- API:application programming interface应用程序编程接口
- 由于String类型是引用类型,所以在对字符串内容进行比较时,需要使用.equals()方法,否则比较的将是两个字符串的地址而非字符串内容
- String类型不可变
String类型在使用String s = “asdasd”进行创建的时候,每一次都会查看常量池中是否存在”asdasd”这个字符串,不存在就新创建一个放在常量池中,随后再给s使用,这样会造成资源的浪费
所以使用StringBuilder进行字符串的创建,StringBuilder在创建字符串时就不会在常量池中新创建了
String内容是不变的,StringBuilder是空白的,内容可变的(可以看做一个容器) - String和StringBuilder的相互转换:
StringBuilder s = new StringBuilder(); s = “123”;
//使用这个方法就可以把StringBuilder抓换成String类型
String s1 = s.toString();
//使用这个方法就可以把String类型转换成StringBuilder类型
String s = “xxx”; StringBuilder s1 = new StringBuilder(s);
/*StringBuilder的方法 StringBuilder.append()添加任意类型的数据,返回给对象本身
因此可以实现链式编程*/
StringBuilder.append(“asx”).append(“123”).append(“xxx”)………
//字符串反转
StringBuilder.reverse()
- 字符串的索引也是从零开始的,和数组一样
- 字符串拼接直接使用+=就可以进行, string += xxx; 后面的元素不限制类型
- 定义方法时要做到两个明确:1、返回值类型明确2、参数类型明确
- 有些时候一行代码就可以实现 比如说实现字符串反转
return new StringBuilder(s).reverse().toString();
//新建了一个接受了String类型的s变量的StringBuilder类型的变量
//然后先翻转再转换成String类型,最后返回
- 集合:存储空间可变的数据模型,集合是引用类型,在方法里的修改就是真实的修改 ArrayList 集合也会索引越界
使用add()方法时,如果add(int index , Eelement);index索引指向的位置如果前后都没有元素就会出现索引越界报错
如果0,1,2,位置都有对象,那么0,1,2,3位置都可以add,4位置进行add就会出现索引越界 - 对方法进行测试时每次只测试一个方法以防其他方法造成影响
- Idea中自动生成get/set方法:alt+Insert,之后就可以选择,自动生成
- System.exit()方法,JVM虚拟机退出
继承
- 继承是面向对象三大特征(继承,封装,多态)之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
使用继承的时机:
如果存在AB两个类,A是B的一种或者B是A的一种时,才应该考虑使用继承 (如果两个类的属性和方法基本相同,那么就应该让他们两个继承同一个父类,父类中就写他们相同的属性和方法,集成之后再在自己类里面定义自己独有的东西)
public class 子类名 extends 父类名{}
优点:提高了代码的复用性,提高了代码的维护性
缺点:增强了类的耦合性,降低了子类的独立性,父类进行修改时,子类不得不跟着变化
- 父类也被称为基类和超类,子类也被称为派生类
- 在子类方法中调用参数,如果方法中有就用方法中的参数,如果方法中没有就在子类中寻找,有就用子类中的参数,子类中还是没有就用父类中的参数
说的是变量名相同情况下(父类int age = 40;子类int age = 20),子类方法会使用子类中的变量,调用时age的值就是20
super关键字 this关键字 想要访问类中同名变量而不是方法中的局部变量,使用this.xxx
而想要访问父类中同名的变量就需要使用super.xxx public class Zi extends Fu {
public int age = 10;
public void show() {
int age = 5;
System.out.println(age);//输出的是5
System.out.println(this.age);//输出的是10
System.out.println(super.age);//输出的是定义在父类中的age 20
}
- 想通过super()来访问父类构造方法,必须将super()写在子类构造方法的第一行子类中的构造方法会默认调用父类中的无参构造方法,不写super()也可以,写是为了实现其他需求,可以使用super(int age)来修改,使子类构造方法默认调用父类中的有参构造方法
- @Override注解可以用来检查重写的方法的正确性(是否和父类中的一样)
- 父类中的Private内容无法被子类继承到,所以也就无法重写 在子类中进行重写的时候,重写的方法访问权限要≥父类即可 在子类中进行重写时也可以直接写父类中方法名自动生成(子类中直接输入eat()IDEA会帮助自动生成)
pubic class Fu{
public void eat(){
sout("父类中的吃");
}
}
public class Zi extends Fu{
public void eat(){
sout("子类中的吃");
}
}
- 方法名前面不写public或private时会有一个默认的访问权限。public>默认>private
- JAVA中类只能继承一个类而不能继承多个类(只支持单继承),但是可以多层继承,儿子继承父亲,父亲继承爷爷
- 共性抽取成父类,如果带参new对象时无法访问到父类中私有的变量,可以在子类的带参构造方法中接受变量,然后super()传递参数给父类从而实现给父类中的私有变量赋值等操作
public class Human {
//这里父类中有一个带参构造方法
public Human(String name , int age){
this.name = name;
this.age = age;
}
public class Student extends Human{
//new子类类型的对象无法访问到父类中private类型的变量,需要使用时可以使用super()传参来对父类中私有类型变量进行操作
public Student(String name, int age) {
super(name, age);
}
}
-
javac -d <目录> -d这个参数是,制定放置生成的类文件的位置 javac -d . .代表的是当前目录
-
(自动创建包).java文件中已经写好了 package com.Mario; cmd命令行中使用 javac -d . HelloWorld.java就会自动创建好包(文件夹)并将.class文件放到对应位置 执行时使用 java com.Mario.HelloWorld
-
(手动创建包)如果没有工具在编程时,创建包的语句格式为:package com.xxx;同时需要在硬盘相应自己创建好包对应的文件夹,然后把编译之后的class文件放进去,最后运行的时候就java com.xxx.Hello(这里是类名)就可以了
-
JAVA中四种权限修饰符:
private 仅在同一个类中才可以进行访问 默认(什么都不写) 用一个包中都可以使用
protected 不同包的无关类就不可以使用了,有关无关暂时指的是继承关系
public import之后所有类都可以进行访问,
-
final关键字 final修饰的基本变量会变成常量,不可修改 final修饰引用变量,由于引用变量存储的是变量的地址,所以无法再修改这个应用变量的地址,也就是不能给他更改对象,但是可以修改该引用变量的内容例:
final int age = 20;
age = 10; ///这里就会报错,因为变量已经变成常量了,不能再修改
final Student s = new Student();
s.age = 10; //它的内容可以修改
s = new Student(); //这里就会报错,因为已经使用final修饰了s,因为他是引用变量,所以s的地址值就已经不能修改了,但是它的内容可以修改
- static关键字 使用static关键字修饰的变量可以让类所有对象共享
Student s1 = new Student();
Student s2 = new Student();
s1.age = 10; //Student类里有一个static int age;
sout(s2.age); //结果是10
后面就不需要每一个new的student都赋值一次年龄了,后面就都是10了 但是这种类型的变量就不建议通过对象去访问了,建议通过类名来访问 Student.age就可以访问并赋值了
一般使用static类型来修饰的变量都是因为它只需要加载一次,后面所有该类行不需要重新赋值。
Student.age = 10;
Student s1 = new Student();
Student s2 = new Student();
sout(s2.age); //结果是10
- static访问的特点 非静态成员方法可以访问所有的静态非静态成员(变量和方法) 静态成员方法只能访问静态成员
多态
- 一个对象在不同时期表现出的不同形态就叫做多态
- 多态实现的三个必要条件:
1、有继承
2、有方法重写
3、有父类对象的子类调用有父类引用指向子类对象 - 多态中 成员访问的特点
//Cat类继承自Animal类
//父类引用指向子类对象
Animal a = new Cat();
成员方法:编译看左边,运行看右边
成员变量:编译看左边,运行看左边
成员方法可以对父类中的方法进行重写,所以运行的时候要看右边
成员变量不能重写,运行只能看左边
- 优点和缺点:
优点:提高程序可扩展性
定义方法时使用父类方法,具体使用时使用子类参与操作
缺点:无法使用子类中特有的方法 - 多态中的向上转型和向下转型
向上转型:可以理解为用父类存储子类,升辈了,向上转型
//Cat类继承自Animal类
//向上转型
Animal a = new Cat();
//向下转型
Cat c = (Cat) a;
向下转型:将父类对象强制转换成子类,降辈了,向下转型
这时对象c就可以使用Cat类中特有的方法了