一、Java概述与基础
1.JDK,JRE,JVM
JDK是 Java 语言的软件开发工具包(SDK)
JRE是运行JAVA 程序所必须的环境的集合 ,但是 jdk包含jre的
JVM 是(Java 虚拟机)的缩写 ,JVM 是实现Java 语言跨平台的法宝。
2.编译
.java文件 — 源文件 (程序员读写)
编译
.class文件 — 字节码文件,给虚拟机读取运行
3.类与main方法的创建
main方法是程序的入口
public class HelloWorld{
public static void main(String[] rags){
}
}
4.dos命令(了解)
开发仍然用图形化界面操作电脑,不适用dos命令来操作
dir 查看当前目录下的所有内容
cd . 刷新当前目录
cd .. 上一级目录
相对路径和绝对的区分:
绝对路径是有根目录的,盘符就是根目录
D:\course---绝对路径不能跨盘符
admin ---- 相对路径是只能相对于当前路径
cd 相对路径
cd 绝对路径
磁盘:切换盘符
del 文件名 删除文件
del *.txt 删除当前目录下的所有txt文件
del 目录 提示是否删除当前目录下的所有文件
echo ->文件全名 创建文件
ipconfig 查看本机IP地址
ipconfig/All 查看所有 包含mac地址 (物理地址)
cls 清除屏幕
exit 退出
5.类的注意事项
如果不用public修饰类,那么可以类名和文件名不一致
1 . 一个java文件中可以有多个类,但是只能有一个是public修饰
一个java文件中 有多少个类,就产生多少个class文件
2 . 一个类没有main方法,可以编译,不可以运行!
一个类中只能有一个main方法,mian方法体中也不能嵌套main方法
6.快捷方式
shift + shift 快速找到类
ctrl+f 查找要的内容
psvm main方法
sout 输出语句
Ctrl+Alt +L 格式化代码
Ctrl + Shift + F10 运行
Ctrl + /添加/删除单行注释
Ctrl + Shift + /添加/删除多行注释
Alt + Enter 自动修正
Ctrl + z 撤销
Ctrl + D 复制当前行
Shift + F6重命名
Ctrl+Alt+v 快速返回值类型
Alt + 鼠标左 多行编辑
Ctrl+Alt+z 补充代码----查询一下
\反斜杠(转义符)
\n表示换行
\t表示空格
7.权限修饰符
权限就是被访问的权限
权限修饰符可以修饰类,修饰(成员)方法,修饰成员变量,不可修饰局部变量!
成员变量称为类的属性,成员方法称为类的方法
局部变量指的是方法体内的变量
private 私有化的 只能在当前类使用!
private 不能修饰外部类,只能修饰内部类
default默认的 ,不用任何词修饰就是默认的!
同一个包中可以使用!
protected 关键字 受保护的
异包&继承
子类中使用父类用protected修饰的内容
public 公开的 整个项目都可以使用
一般情况:
类用public修饰
成员变量用private修饰
成员方法public修饰
private ->默认的->protected->public
private可以修饰抽象内部类吗?可以!
private可以修饰抽象方法吗?不可以!
8.bs架构和cs架构
bs: 不需要下载客户端,把浏览器作为客户端
cs: 需要下载客户端
9.程序执行的过程
1.写*.java
2.编译,把*.java编程*.class
3.类加载(把class文件加载到虚拟机中)
4.执行程序
10.环境配置
JAVA_HOME: jdk安装目录
path: %JAVA_HOME%\bin
11.快捷方式
shift + shift 快速找到类
ctrl+f 查找要的内容
psvm main方法
sout 输出语句
Ctrl+Alt +L 格式化代码
Ctrl + Shift + F10运行
Ctrl + /添加/删除单行注释
Ctrl + Shift + /添加/删除多行注释
Alt + Enter 自动修正
Ctrl + z 撤销
Ctrl + D复制当前行
Shift + F6重命名
Ctrl+Alt+v 快速返回值类型
Alt + 鼠标左 多行编辑
Ctrl+Alt+z 补充代码----查询一下
二、基础语法
1. 注释
//单行注释
2. 关键字与标识符
-
关键字 系统赋予特定含义的单词叫关键字,关键字特点全小写
-
标识符 自己命名的部分叫标识符
-
标识符规范:
1.标识符是由字母,数字,下划线,美元符号组成
2.数字不能开头
3.关键字和保留字不能作为标识符
4.中文和¥一般情况下可以作为标识符,但是开发禁用! -
开发规范:类 – 每个单词的首字母大写
3. 8种基本数据类型
1. 整数类型 : byte short int long
取值范围 占用字节数
byte -128 到 127 1
short 正负3万多 2
int 正负21亿左右 4
long 最大范围 8
2. 小数类型(浮点类型):double float
浮点数 占用字节数 精确度
float 4 单精度
double 8 双精度
3. 逻辑类型: boolean
boolean 占用1字节
字面值只有两个
true(对,正确,成立。。。)
false(错,错误,不成立。。。)
true和false是关键字,因为系统赋予特定的含义,并且全小写!
4. 字符类型: char
char 取值范围0到65535 占用2个字节
char更多表示单个的字符,就是字符串中的一个!
// 如果表示的十进制数字通过ASCII码对照表能对应一个图形,就会输出图形
“abc”--->'a'
5. (非基本数据类型)字符串:String
6. 精简掌握 整数用int 小数double 字符串用String
4. 数据类型转换
能够参与类型转换的数据类型只有7种
按照容量范围的顺序排序? 从小到大排序
byte -> short(char)-> int -> long -> float -> double
自动类型转换
//小容量转换大容量,不需要任何修饰不会报错!
强制类型转换
大容量转换小容量,强制要求加 强制类型转换符
强制转换类型2个问题:溢出、精度丢失
int m=100;
byte n=(byte)m;
System.out.println(n);
int m=100;
char n=(char)m;
System.out.println(n);
两个不同类型运算的结果是大的类型
例:int a=10;
double b=20.0;
double c=a+b;
System.out.println(c);
byte a1=10;
short a2=20;
short a3=(short)(a1+a2);
System.out.println(a3);
5. print和println的区别
print和println区别
第一个区别:
println是先输出内容,然后换行(Enter)
print 不换行一行输出
第二个区别:
println()小括号可以什么都不写
print()小括号必须写内容,不写就报错
6. Scanner和Random
Scanner控制台输入
//1.创建Scanner对象---用户可以在控制台输入内容了
Scanner sc=new Scanner(System.in);
// name获取到用户输入的内容
String name = sc.next();
raondom
Random随机数
//1.创建Random对象
Random rd = new Random();
//2.调用方法
int x = rd.nextInt(5)+1;
System.out.println(x);
7. continue,break,return
continue 跳出当次循环
break 结束当前整个循环 在switch语句中结束swtich语句
return 结束当前方法
三、运算符
1.算术运算符
+ - * / %( 取模 求余数) ++ --
2.赋值运算符
= += -= /= *= %=
+= a+=2 // a=a+2
-= a-=2 // a=a-2
/= a/=2 // a=a/2
*= a*=2 // a=a*2
%= a%=2 // a=a%2
3.比较运算符
> < >= <= == !=(不等于)
比较运算符的结果一定是boolean类型的字面值
== 是比较 = 是赋值
4.逻辑运算符
& 并且,与 | 或者 !非 ^异或 ||短路或 &&短路与
! 把一个条件的结果反向
|| 第一个条件为真则不会执行后续条件,为假则执行后续条件
&& 第一个条件为假则不会执行后续条件,为真则执行后续条件
比较的结果都是boolean类型的字面值
5.三目运算符
语法: 数据类型 变量名 = 条件表达式 ? 字面值1 :字面值2;
int a = 3>2 ? 1 : 2;
含义:如果条件表达式结果是true 那么 a的值是1
如果条件表达式结果是false 那么 a的值是2
四、控制语句
1.if语句
if语句
语法:if(条件表达式){if体 }
含义:条件成立,执行if体!条件不成立,不执行
2.if-else语句
if-else语句
语法:if(条件表达式){if体}else{else体}
理解:条件成立,执行if体,条件不成立,执行else体
3.if-else-if多分支语句
- if-else-if多分支语句
语法:if(条1){体1} else if(条2){体1} else if(条3){体3} … else{else体 }
理解:如果条1成立,执行体1,程序结束
如果条1不成立,继续判断条2,如果条2还不成立,继续判断
如果所有的条件都不成立,执行else体,如果期间遇到一个成立,执行那个成立的,程序就结束了
4.switch语句
- switch语句
语法: switch(字面值){
case 字面值1:
输出语句,变量。。。
break;
case 字面值2:
输出语句,变量。。。
break;
case 字面值3:
输出语句,变量。。。
break;
…
default:
输出语句,其他。。。}
理解:switch的字面值跟case的字面值相等,就执行case语句,如果所有的 case 跟switch的字面值不相等,执行 default语句
case并列: case 6: case 7: case 8:
System.out.println(“夏天”);
break;
5.循环语句
[1] for循环
for循环
语法:for(初始表达式;条件表达式;迭代语句){循环体}
理解:
初始表达式执行,条件表达式执行,如果成立,执行循环体,执行迭代语句,再执行条件表达式
初始表达式执行,条件表达式执行,如果不成立,循环结束!
[2] while循环
while
语法:while(条件表达式){循环体 }
解释:条件成立,执行循环体,然后再判断条件,如果还成立,继续执行循环体,直到条件不成立为止!
[3] do-while循环
do-while
语法:do{循环体}while(条件表达式);
解释:先执行循环体,然后条件判断,如果成立继续执行循环体,然后再判断
直到条件表达式不成立为止!
三种循环 for while do-while
后期数组集合,遍历,多使用for循环
while循环可以使用死循环更多一些,迭代器遍历!枚举遍历!
do-while使用较少!
基础性面试题
while do-while区别?
while循环是先判断后执行循环体
do-while先执行一次循环体再判断
如果一个程序,第一次条件就不成立,那么do-while也能执行一次循环体!
案例代码
打印2 到100 的所有素数,每行显示5 个素数。
public static void main(String[] args) {
int d =0;
for (int a =2;a<=100;a++) {
boolean c = true;
for (int b = 2; b <= a - 1; b++) {
if (a % b == 0) {
c = false;
break;
}
}
if (c) {
System.out.print(a+"\t");
d++;
if (d==5){
System.out.println();
d=0;
}
}
}
}
编写java 程序,打印如下的数值列表:
1 10 100 1000
2 20 200 2000
3 30 300 3000
4 40 400 4000
public static void main(String[] args) {
int sum;
for(int j=1;j<=4;j++){
sum=j;
for(int i=1;i<=4;i++){
System.out.print(sum+"\t");
sum*=10;
}
System.out.println();
}
编写程序输出下图:
*
***
*****
public static void main(String[] rags){
int hang = 4;
for (int a =1;a<=4;a++){
for (int c=1;c<=hang-a;c++) {
System.out.print(" ");
}
for (int b =1;b<=a*2-1;b++){
System.out.print("*");
}System.out.println();
}
}
五、方法/函数
1.方法概述
方法的基本语法
方法java中又叫函数! main方法,mian函数!
语法:权限修饰符 返回值 方法名(参数){ }
返回值:
1.无返回值类型 使用关键字void表示
2.有返回值类型
返回值类型,是任意数据类型(byte short int long float double char boolean String)
有返回值类型,必须在方法体最后一行写 return 字面值;
return 字面值;含义:结束方法之前,把字面值给出去!
字面值一定要与返回值类型匹配!
return和return 字面值; 不同,
return只有结束方法的含义!
return 字面值; 结束方法之前,把字面值给方法外部!
方法名:自定义标识符
类名为首字母大写,
变量名和方法名,第一个单词全小写,第二个单词开始首字母大写!
自定义方法跟main方法关系?
main方法的方法体不能写自定义方法!--- 方法之间不能嵌套
自定义方法不能直接运行,可以通过main来调用执行!
2.方法重载
方法重载语法:
同一个类中,两个及两个以上的方法,方法名完全一致,参数列表不一致,跟其他任何内容无关!
参数列表不一致/满足任一条件:
1.参数个数不同
2.参数类型不同
3.参数的类型的顺序不同
方法重载的应用
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(fun(1,5));
System.out.println(fun(1,5,10));
}
public static int fun(int a,int b){
return a>b? a:b;
}
public static int fun(int a,int b,int c){
return fun(fun(a,b),c);
}
3.递归
递归:方法自己调用自己(可控!)
递归应用
输出1到10
static int i=1;
public static void main(String[] args) {
fun();
}
public static void fun(){
System.out.println(i);
i++;
if(i<=10){
fun();
}
}
通过递归计算N的阶乘
static int sum =1;
static int i =1;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字计算阶乘");
int a = sc.nextInt();
System.out.println(fun1(5));
}
public static int fun1(int n){
sum*=i;
i++;
if (i<=n){
fun1(n);
}
return sum;
}
六、面向对象
1.面向对象概述
面向对象依赖面向过程的!
类是构建对象的模板
类是抽象的,对象具体的
类是大量对象的共性的抽象
成员变量是直接在类体中
局部变量在方法体中
局部变量不初始化,输出使用直接会报错!
成员变量不初始化,有默认值!
成员变量默认值
int 0
double 0.0
boolean false
char '\u0000'
String null
2.普通类的创建
类分两种,一种有main一种没有main!
有main的是要运行的,一般叫 ---- 测试类!
没有main的,不需要运行,为了创建对象-------模板类(实体类)!
模板类
活体,人类=属性+行为
物体,手机类=属性+功能
3.通过类创建对象
语法:类名 对象名 = new 类名();
对象名:标识符,随意取,开发规范,跟变量一样
new: 关键字,在堆内存中开辟一块儿新的空间!
总结
1.通过模板类能够创建对象
2.对对象的属性赋值
3.可以输出对象的属性值
4.可以调用对象的方法
4.类作为引用数据类型
所有的类都可以看作是一种引用数据类型
Person是引用数据类型
把new Person()对象字面值赋值给p1,p1是Person类型
Person p1=new Person();
int基本数据类型
把10这个字面值数据赋值给a,a是int类型
int a =10;
5.类作为成员变量
//丈夫类
public class Husband {
//属性:名字 年龄 妻子
String hbdName;
//Wife是一种自定义的引用数据类型
Wife w;
//通过Wife类创建的对象都可以赋值给w,等同于Person类创建多个对象赋值给p1,p2
// Person p1=new Person();
// Person p2=new Person();
}
//妻子类
public class Wife {
String wifeName;
}
public static void main(String[] args) {
Wife w1 = new Wife();
w1.wifeName="孙尚香";
Husband h1 = new Husband();
h1.hbdName="刘备";
h1.w=w1;
System.out.println(h1.hbdName+"--------"+h1.w.wifeName);
}
6.类作为参数类型
任何类都是一种引用数据类型
把类作为属性成员变量
丈夫类和妻子类
面向对象关注的是对象
饲养员给熊猫喂食
哪个饲养员?哪个熊猫?
任何饲养员喂食任何熊猫!
饲养员类 ---- 属性:名字 动作:喂食
熊猫类 ----属性:名字 动作:吃竹子
package cn.bjpowernode.javase01.day13.classes;
//熊猫饲养员
public class KeeperPanda {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public KeeperPanda(String name) {
this.name = name;
}
public KeeperPanda() {
}
//喂熊猫--- 喂一个具体熊猫,---喂一个熊猫对象
//具体的熊猫对象是 Panda类型
public void feed(Panda panda){//=new Panda("盼盼");
System.out.println(name+"喂:"+panda.getName());
panda.eat();
}
}
package cn.bjpowernode.javase01.day13.classes;
//熊猫类
public class Panda {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Panda(String name) {
this.name = name;
}
public Panda() {
}
public void eat(){
System.out.println(name+"吃竹子!");
}
}
package cn.bjpowernode.javase01.day13.classes;
public class Test {
public static void main(String[] args) {
Panda p1 = new Panda("盼盼");
KeeperPanda k1 = new KeeperPanda("刘备");
k1.feed(p1);
}
}
7.类作为返回值类型
创建对象和使用对象分离----解耦合!
Person p1=new Person();
p1.eat();
package cn.bjpowernode.javase01.day13.classes02;
//苹果类
public class Apple {
public void eat(){
System.out.println("吃苹果。。。");
}
}
package cn.bjpowernode.javase01.day13.classes02;
//苹果工厂,java中不管什么工厂都是生成对象的!---- 工具类
public class AppleFactory {
//方法:谁调用这个方法,给它一个苹果Apple对象
public static Apple getInstance(){
return new Apple();
}
}
package cn.bjpowernode.javase01.day13.classes02;
public class Test {
public static void main(String[] args) {
Apple a11 = AppleFactory.getInstance();
Apple a22 = AppleFactory.getInstance();
Apple a33 = AppleFactory.getInstance();
a11.eat();
a22.eat();
a33.eat();
}
}
8.构造函数
语法:【public】类名(【参数】){}
构造函数,是创建对象的时候被调用的!
构造函数作用
1.创建对象依赖构造函数
一个类没有手动写任何构造函数,也会有一个构造函数(默认的,隐式的,无参的),为了满足创建对象的依赖
一个类如果手动写了构造函数,就不会再生成那个(默认的,隐式的,无参的)构造函数
一个类如果写了有参构造,应该把无参构造也写出来!
2. 给属性初始化
空指针异常
NullPointerException 空指针异常
原因:一个变量,引用的对象是null,在堆内存不开辟空间,更没有属性和方法,这个时候,去调用就会出现 空指针异常!
9.函数/方法之间的调用
非静态方法既可以调用静态属性和方法也可以调用非静态属性和方法!
调用静态的属性和方法时,省略的是类名,调用非静态的属性和方法时省略的是this
静态方法只能调用静态属性和静态方法,省略的都是类名!
构造函数可以调用静态的属性和方法,也可以调用非静态的属性和方法
总结:非静态方法什么都能调用(构造函数除外)
静态方法只能调用静态成员
构造函数什么都能调用
七、对象的封装
1.封装概述
面向对象三大特征:封装,继承,多态
封装是一种思想,课件中只是属性的封装!
封装理解:包装 更安全!
属性封装,数据更安全!
- 为什么学习封装?
用户可以随意给值,不符合实际情况的年龄也是可以赋值的,数据就无效!
2.封装步骤
private 关键字 私有化的
private 可以修饰内部类,private可以修饰成员变量,private可以修饰成员方法
属性封装,主要使用private修饰属性--成员变量
private 修饰的内容,只能在当前类中使用!
第一步:private修饰属性(其他类不能直接操作属性)
第二步:提供公开的(public)设置值的方法(set方法)
第三步:提供公开的(public)获取属性的方法(get方法)
public class Student {
String name;
private int age;
//给age设置值!
public void setAge(int age){
if(age>0 && age<130){
this.age=age;
}else {
System.err.println("年龄设置不合理,默认年龄18!");
this.age=18;
}
}
//返回age
public int getAge(){
return age;
}
}
//main方法
public static void main(String[] args) {
Student s1 = new Student();
s1.name="张三";
//s1.age=20;
s1.setAge(2000);
// System.out.println("名字:"+s1.name+"\t年龄:"+s1.age);
System.out.println("名字:"+s1.name+"\t年龄:"+s1.getAge());
}
八、This和Static
1.this关键字
this指向
this 当前对象
类的非static方法中使用this,表示当前对象,这个方法被哪个对象调用,this就是哪个对象!
this可以区分成员变量和局部变量
this在构造函数之间的调用
语法:this(【实参】); 必须在第一行!
构造函数中没有递归,也不能相互调用,影响创建对象!
构造函数可以直接调用非构造函数!
构造函数之间调用的意义?
无参构造去调用有参构造可以,提高代码的重复利用率!
2.static关键字
public static void main(String[] args){ }
static 静态的
static可以修饰内部类(过几天再讲)
static可以修饰属性 ========
static可以修饰方法 ========
static可以修饰代码块 ========
static修饰成员变量,静态变量!
static修饰属性,静态属性!
static不能修饰局部变量
static修饰的内容都倾斜,在idea中!
结论:
一处设置处处设置,一处修改处处修改!
当遇到很多对象都有同一个属性的值,这个时候用static修饰这个属性!
static修饰方法(重点调用)
static修饰的方法就叫静态方法,没有static修饰的方法,叫非静态方法
使用工具类的方法
类名.静态属性/静态方法
3.static代码块
{ } 非静态代码块
static{} 静态代码块
除了明显的死循环,其他内容都可以写,跟方法体没什么区别
静态代码块儿只能调用静态的成员,非静态代码块什么都能调用
规律:
一个类中有静态代码块,非静态代码块,构造函数
如果创建对象,执行顺序:
静态代码块先执行
非静态代码块执行
构造函数执行
如果多次创建对象,非静态代码块和构造函数执行多次,静态代码块执行一次
4.方法区(1.7)
对象为空,调用静态方法和静态属性都不会出现空指针异常NullPointerException
类加载是遇到什么加载什么!
静态区:类加载时,遇到静态内容都存储到静态区!
九、继承
1.继承概述
继承,继承财产
继承是类与类直接的关系的表示
子类继承父类
父类可以有私有的内容 ,子类不可继承!
子类也可以有独有的方法,跟父类不一样!
2.继承的关系区分
子类 继承 父类
Account 4个属性 CreditAccount 5个属性
继承的关系? ---- 从属关系
父类更通用(抽象),子类更具体!
信用卡属于银行卡的一种! CreditAccount is a Account!
3.继承的语法特性
extends 关键字 延伸,继承
1.子类extends父类
public class Zi extends Fu {}
2.子类继承父类,继承父类所有的属性和方法(私有化,构造方法 除外)
属性封装,要求属性必须私有化,私有化的不能继承,那么属性封装和继承存在矛盾吗?不存在,属性封装要求属性私有化的同时还要提供公开的,get和set方法,那么get和set是可以被继承的,所以继承和封装一起使用,不存在矛盾!
子类所有的构造函数,都隐式的,默认的调用父类的无参构造。。。
构造函数是调用关系,不是继承关系!
子类不管什么构造函数运行时都会调用父类的无参构造
3.java中继承都是单继承,一个子类只能有一个父类
单继承会让子类的功能强大缺失,弥补功能的问题,支持间接多继承!
4. A -> B -> C -> D -> E 继承缺点,耦合度过高!
耦合度:连系性,关联性太强!父类出问题,子类都出问题!
手机 耦合度高的产品
台式电脑 耦合度低,高内聚
低耦合,高内聚!
5.继承分两个内容,一个是隐式继承,一个是显示继承
显示继承:写extends就是显示!
隐式继承:任何类都直接或者间接继承Object类!
一个类没有直接继承其他类,它一定隐式继承Object类
一个类显示继承了其他类,它一定间接继承Object类
4.静态内容是否能继承?
静态内容都可以继承的,但是子类和父类调用的是同一个静态内容,可以不去继承的!
package cn.bjpowernode.javase01.day12.extends04;
public class Fu {
int a;
static int b;
public void fun1(){}
public static void fun2(){}
}
package cn.bjpowernode.javase01.day12.extends04;
public class Zi extends Fu {
}
package cn.bjpowernode.javase01.day12.extends04;
public class TestZi {
public static void main(String[] args) {
Zi zi = new Zi();
System.out.println(zi.a);
// System.out.println(zi.b);---警告
System.out.println(Fu.b);
System.out.println(Zi.b);
zi.fun1();
// zi.fun2();
Zi.fun2();
Fu.fun2();
}
}
5.方法的覆盖/重写
方法的重载overload
方法的重写override
为什么用方法的重写?
父类比子类更抽象的,方法也比子类更抽象,父类方法无法满足子类需求
package cn.bjpowernode.javase01.day12.override02;
//猴子
public class Monkey {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//方法:
public void speak(){
System.out.println("猴子说猴语。。。");
}
}
package cn.bjpowernode.javase01.day12.override02;
//人类
public class ChinesePeople extends Monkey{
}
重写的语法
1.权限修饰符子类要大于等于父类
protected(权限小) public(权限大)
2.返回值类型,子类必须和父类一致
3.方法名和参数类型,子类必须和父类一致
4.子类不能比父类抛出更多异常(第二阶段让老师演示一下!!!)
5.重写主要修改的是方法体!
Alt+Insert生成,开发! @Override 注解==============
6.静态方法是否能重写?
静态方法不能被重写
使用Alt+Insert 没有重写的
父子都有静态方法,都是各自跟各自类绑定
多态可以再次证明!
静态方法可以被继承,但是不可以被重写!
重写和重载区别?
重载:同一个类中,两个及两个以上的方法,方法名相同,参数列表不同,跟其他无关!
重写:继承关系中,父类的方法,不能满足子类需求,子类需要建立在父类方法基础上改造成子类需要的方法
7.子类构造函数调用父类构造函数意义
this无参调用有参提高代码的重复利用率
package cn.bjpowernode.javase01.day12.superdemo02;
public class Demo {
String name;
int age;
public Demo(String name, int age) {
this.name = name;
this.age = age;
}
//属性初始化
public Demo() {
// this.name="刘备";
// this.age=18;
this("刘备",18);
}
}
super调用父类的构造函数,提高代码的重复利用率
package cn.bjpowernode.javase01.day12.superdemo02;
public class Account {
private String acID;
private String username;
private String password;
private double balance;
public String getAcID() {
return acID;
}
public void setAcID(String acID) {
this.acID = acID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public Account(String acID, String username, String password, double balance) {
this.acID = acID;
this.username = username;
this.password = password;
this.balance = balance;
}
public Account() {
}
}
package cn.bjpowernode.javase01.day12.superdemo02;
public class CreditAccount extends Account {
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public CreditAccount(){}
public CreditAccount(String acID, String username, String password, double balance,int score){
// super.setAcID(acID);
// super.setBalance(balance);
// super.setPassword(password);
// super.setUsername(username);
super(acID,username,password,balance);
this.score=score;
}
}
package cn.bjpowernode.javase01.day12.superdemo02;
public class Test {
public static void main(String[] args) {
CreditAccount c = new CreditAccount("21465465","刘备","12345",1000,200);
}
}
Alt+Insert====生成构造函数!
8.继承的内容
package cn.bjpowernode.javase01.day12.extends05;
public class Fu {
int a;
static int b;
public void fun1(){
System.out.println("fun1...");
}
public static void fun2(){
System.out.println("fun2...");
}
}
package cn.bjpowernode.javase01.day12.extends05;
public class Zi extends Fu {
int c;
static int d;
public void fun3(){
System.out.println("fun3...");
}
public static void fun4(){
System.out.println("fun4...");
}
public void info(){
//非静态的---------------
System.out.println(this.a);
System.out.println(super.a);
super.fun1();
this.fun1();
fun1();
//静态的------------------
System.out.println(this.b);
System.out.println(super.b);
System.out.println(Fu.b);
System.out.println(Zi.b);
super.fun2();
this.fun2();
Fu.fun2();
Zi.fun2();
}
}
package cn.bjpowernode.javase01.day12.extends05;
public class Test {
public static void main(String[] args) {
Zi zi = new Zi();
zi.a=50;
zi.info();
}
}
十、Super
this和super对比学习
this:当前对象
this在非静态方法中使用,谁调用这个方法,this就是这个对象!
super:父类特征
super在子类的非静态方法中使用,指向父类的属性和方法!
public void fun(){
System.out.println(this);
//System.out.println(super);错误的,super不是对象不能直接输出
}
this使用场景:
1.默认使用
2.有参构造对属性初始化,this.属性=属性
set方法,this.属性=属性
区分成员变量和局部变量,this不可省略!
3.构造函数之间相互调用使用this(【实参】); 第一行
super使用场景:
1.默认使用
2.super.方法()
如果在重写的方法中调用父类的方法,super不可省略
3.子类调用父类构造函数super(【实参】);第一行
子类所有的构造函数都默认的隐士的调用父类的无参构造
this()和super()不能在同一个构造函数中使用!
父类如果没有无参构造,子类所有的构造函数都必须手动调用父类的有参构造
十一、多态
1.多态概述
多态,多种形态。
作用,降低代码的耦合度
多态含义:同一个动作,在不同的环境,出现不同的结果
在桌面按F1,浏览器帮助中心 在word文档中,按F1,得到word的帮助中心
同一个方法,传递不同的参数,运行的是不同的内容!
2.多态语法
多态前提条件:继承 重写
达到多态三个条件:1.继承 2.重写 3.向上转型(自动类型转换)
特点:多态形式,只能调用重写的方法,执行的是子类的方法
不能调用子类独有的方法!
package cn.bjpowernode.javase01.day13.polymorphic01;
//动物类
public class Animal {
public void eat(){
System.out.println("动物吃。。。");
}
}
package cn.bjpowernode.javase01.day13.polymorphic01;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头。。。");
}
//狗!
public void lookDoor(){
System.out.println("看门。。。");
}
}
package cn.bjpowernode.javase01.day13.polymorphic01;
public class Test {
public static void main(String[] args) {
//向上转型,自动类型转换
// 10是整数字面值 int类型,自动提升为double
double b=10;
//new Dog() 对象字面值,Dog类型,自动提升为Animal
Animal d1 = new Dog();
d1.eat();
// d1.lookDoor();
}
}
十二、final关键字
面试题
package cn.bjpowernode.javase01.day14;
public class Fu {
int a=10;
static int b=20;
public void fun(){
System.out.println("fun...父");
}
public static void info(){
System.out.println("info...父");
}
}
package cn.bjpowernode.javase01.day14;
public class Zi extends Fu {
int a=100;
static int b=200;
@Override
public void fun() {
System.out.println("fun...子类");
}
public static void info(){
System.out.println("info...子类");
}
}
package cn.bjpowernode.javase01.day14;
public class TestZi {
public static void main(String[] args) {
Fu fu = new Zi();
fu.fun();//子类。。。
// fu.info();//父类
System.out.println(fu.a);//10
// System.out.println(fu.b);//20
// 方法看等号右边,属性看等号左边
}
}
静态。。。
package cn.bjpowernode.javase01.day14.test02;
public class Demo {
int i;
static Demo d1 = new Demo();
public static void main(String[] args) {
Demo d2= new Demo();
}
public Demo(){
System.out.println(i++);
}
static {
System.out.println("我是静态代码块。。。");
}
}
输出结果。。。
0
我是静态代码块。。。
0
package cn.bjpowernode.javase01.day14.test02;
public class Demo02 {
int i=print("m:");
static Demo02 d1 = new Demo02();
public static void main(String[] args) {
Demo02 d2= new Demo02();
}
static {
System.out.println("我是静态代码块。。。");
}
public Demo02(){
System.out.println(i++);
}
public int print(String name){
System.out.println(name);
return 100;
}
}
1.final关键字概述
final 最终的,final修饰的内容不可更改!
1. final修饰的变量是常量,不可更改!作为成员变量常量全大写!
成员常量,可以不直接给初始值,但是所有的构造函数必须给它初始值!
2.final修饰的方法不能被覆盖!
3.final修饰的类不能被继承!
4.final修饰对象,内存地址不可变!
2.类的封装
设计模式是为了解决问题的!
单例模式
单例:一个类只能有一个实例! 私有化构造函数
饿汉模式
懒汉模式
[1]饿汉模式
package cn.bjpowernode.javase01.day14.singlecase;
// 这个类只能有一个实例
public class EagerSingleTon {
private static final EagerSingleTon e=new EagerSingleTon();
//阻断一个类new对象
private EagerSingleTon() {
}
//提供get方法,让其他类获取到这个类的对象!
public static EagerSingleTon getInstance(){
return e;
}
}
[2]懒汉模式
package cn.bjpowernode.javase01.day14.singlecase;
//懒汉类
public class LazySingleTon {
private static LazySingleTon e;
//阻断new对象
private LazySingleTon(){ }
//提供一个get方法让其他类可以获取对象
public static LazySingleTon getInstance(){
if(e==null){
e=new LazySingleTon();
}
return e;
}
}
饿汉模式 和 懒汉模式?
饿汉模式:不管使用还是不使用这个对象,只要用到这个类,那么就会在类加载的时候把对象创建好!
一旦使用这个对象,效率高,缺点,占用内存!
懒汉模式:使用这个对象才会创建这个对象,优点是节省内存,缺点,效率低
十三、抽象类
1.抽象类概述
抽象类比普通类更抽象一些,作为普通类的完善
在继承关系中,父类更通用(抽象),子类更具体,往往把父类描述成抽象类!
2.抽象类语法特性
abstract 抽象的 关键字
1.abstract修饰的类是抽象类
public abstract class Demo{ }
2.abstract修饰的方法是抽象方法,抽象方法没有方法体,只能存在于抽象类中
3.有抽象方法的类一定是抽象类,抽象类不一定有抽象方法!
抽象类只是比之前的类能多写抽象方法而已
4.抽象类不能实例化对象
5.抽象类的子类必须重写(实现)父类的抽象方法,除非子类也是抽象类
6.抽象类不能用final修饰,抽象方法不能用final修饰
什么用抽象类?
通用的类,父类!
练习-----------------
形状类 方法:求面积
圆形 方法:求面积
长方形 方法:求面积
正方形 方法:求面积
十四、接口
1.接口概述
接口,usb接口,可插拔
接口规范,也是定义的协议标准
2.接口语法
1.把类的class替换成interface就表示一个接口
2.接口中的成员变量是常量,默认必须用public static final修饰,可以省略不写!
3.接口中的方法都是默认必须用public abstract修饰,可以省略不写!
接口 = 常量(public static final)+抽象方法(public abstract)
4.接口不能被实例化对象
5.接口中没有构造函数
6.实现类实现接口必须重写接口中所有的抽象方法,除非实现类是抽象类
接口和实现类的关系: 理解成继承关系,使用连接的关键字不是extends,而是implements!
implements 关键字,表示类与接口的继承关系!
public interface Demo{ }
public class DemoImpl implements Demo{ }
7.一个实现类可以同时实现多个接口!
8.一个类可以继承一个类的同时,实现多个接口!
public class B extends A implements C,D {
}
9.接口打破单继承,一个接口可以继承多个接口!
public interface C extends A,B {
}
类与类之间用extends 类与接口之间implements
接口与接口之间extends
10.类强调的是从属关系,接口强调的是功能
11.接口可以使用多态!
总结:
1.把class变成interface
2.接口=常量(public static final)+抽象方法(public abstract)
3.接口没有构造函数也不能实例化对象
4.一个实现类可以实现(implements)多个接口,实现接口中所有的抽象方法,除非实现类是抽象类
5.一个接口可以继承多个接口
6.一个类可以继承一个类的同时,实现多个接口(先继承后实现!)
7.接口可使用多态,接口强调功能,类强调所属关系!
设计理念不同!
总结接口和抽象类概念不同:
相同:
1.都能写抽象方法
2.子类都要实现抽象方法,除非子类是抽象类
3.都不能实例化对象
不同:
抽象类,可以有任何变量,接口只能有常量
抽象类可以有非抽象方法,接口必须都是抽象方法
抽象类单继承,实现类可以实现多个接口,且接口能继承多个接口
抽象类有构造函数,接口没有构造函数
类强调从属关系,接口强调功能
2. 1.8接口的新特性
用static修饰可以写方法体
用default修饰可以写方法体
package cn.bjpowernode.javase01.day15.test;
public class Test {
static int a;
static Test t=new Test(500);
int b=print("b:");
static{
System.out.println("我是静态代码块。。。");
System.out.println(t.b);
}
public Test(int b) {
this.b=b;
System.out.println("无参构造。。。"+(++a));
}
public int print(String str){
System.out.println(str);
return 100;
}
public static void main(String[] args) {
Test t2 = new Test(300);
System.out.println(t2.b);
}
}
十五、Object类和内部类
学习类就是要学习类中一些方法
Object类是根类
以下为object类的方法
1.hashCode()方法
返回值int类型
含义:两个对象的内存地址相对,哈希值相等,两个对象内存地址不同,哈希值不同!
哈希值:内存地址转换的整数,不是java实现的!
应用场景:
哈希表(散列表)是数据结构
HashMap是集合
HashMap的底层原理是哈希表
哈希表需要hashCode()的支持!
哈希冲突:不同的两个对象,不同的内存地址,相同的哈希值
public class Student {
@Override
public int hashCode() {
//调用父类Object的方法
return super.hashCode();
}
}
public class TestStudent {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1==s2);
System.out.println(s1.hashCode() == s2.hashCode());
}
}
学习一个方法: xxx()
1.什么含义?(查询api文档,百度,代码试一下)
2.为什么学?应用的场景
3.查看源码,怎么实现的?
2.toString()方法
返回值 String
含义:对象的字符串表示形式
全限定类名+@+16进制(哈希值转换过来的16进制)
直接输出对象,跟输出对象直接调用未重写的toString()方法是一样的!
应用场景:重写输出属性值!
以后再写javabean实例类,建议把toString一块儿生成!
源码:
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode);
}
3.equals()方法
返回值boolean 参数Object obj
含义:object类中的equals方法比较两个对象,比较的是内存地址
作用:
== 也是可以比较对象的,equlas也是可以比较对象的
区别:
==既可以比较基本数据类型,也可以比较引用数据类型(内存地址)
equals只能比较引用数据类型(对象)
源码:public booelan equals(Object obj){
return this==obj;
}
4.内部类
内部类调用外部类的成员
外部类调用内部类成员
测试类调用内部类成员
- 实例内部类
一个类的类体嵌套另外一个类
内部类直接调用外部类的成员,省略的是 外部类.this
外部类通过创建内部类对象调用内部类的成员
测试类创建对象调用内部类的成员
语法:外部类.内部类 对象名 = new 外部类().new 内部类();
- 静态内部类
内部类只能调用外部类的静态成员!
外部类通过内部类类名调用内部类的静态成员,内部类类名不可省略!
测试类,如果调用的是内部类的静态成员,直接 外部类.内部类.成员 调用
如果调用的是内部类的非静态成员,创建对象调用
语法:外部类.内部类 对象名 = new 外部类.内部类();
- 局部内部类
局部内部类是在方法体中,作用域就是方法体
出了方法体,就不能再使用了!
- 匿名内部类
匿名内部类属于特殊局部内部类,存在方法中的,并且只有类体,没有名字和任何修饰!
- 接口创建对象
package cn.bjpowernode.javase01.day15.inner05;
public interface AnimalDao {
void eat();
}
package cn.bjpowernode.javase01.day15.inner05;
public class Test {
public static void main(String[] args) {
AnimalDao dao = new AnimalDao()
//匿名内部类,还是AnimalDao的实现类!
{
@Override
public void eat() {
System.out.println("猫吃鱼。。。");
}
};
dao.eat();
}
}
- 抽象类创建对象
package cn.bjpowernode.javase01.day15.inner06;
public abstract class Animal {
public abstract void eat();
}
package cn.bjpowernode.javase01.day15.inner06;
public class TestAnimal {
public static void main(String[] args) {
Animal a1 = new Animal()
{
@Override
public void eat() {
System.out.println("狗吃骨头。。。");
}
};
a1.eat();
}
}
);
System.out.println(s1.hashCode() == s2.hashCode());
}
}
学习一个方法: xxx()
1.什么含义?(查询api文档,百度,代码试一下)
2.为什么学?应用的场景
3.查看源码,怎么实现的?
## 2.toString()方法
返回值 String
含义:对象的字符串表示形式
全限定类名+@+16进制(哈希值转换过来的16进制)
直接输出对象,跟输出对象直接调用未重写的toString()方法是一样的!
应用场景:重写输出属性值!
以后再写javabean实例类,建议把toString一块儿生成!
源码:
public String toString(){
return getClass().getName()+“@”+Integer.toHexString(hashCode);
}
## 3.equals()方法
返回值boolean 参数Object obj
含义:object类中的equals方法比较两个对象,比较的是内存地址
作用:
== 也是可以比较对象的,equlas也是可以比较对象的
区别:
==既可以比较基本数据类型,也可以比较引用数据类型(内存地址)
equals只能比较引用数据类型(对象)
源码:public booelan equals(Object obj){
return this==obj;
}
## 4.内部类
内部类调用外部类的成员
外部类调用内部类成员
测试类调用内部类成员
* 实例内部类
一个类的类体嵌套另外一个类
内部类直接调用外部类的成员,省略的是 外部类.this
外部类通过创建内部类对象调用内部类的成员
测试类创建对象调用内部类的成员
语法:外部类.内部类 对象名 = new 外部类().new 内部类();
* 静态内部类
内部类只能调用外部类的静态成员!
外部类通过内部类类名调用内部类的静态成员,内部类类名不可省略!
测试类,如果调用的是内部类的静态成员,直接 外部类.内部类.成员 调用
如果调用的是内部类的非静态成员,创建对象调用
语法:外部类.内部类 对象名 = new 外部类.内部类();
* 局部内部类
局部内部类是在方法体中,作用域就是方法体
出了方法体,就不能再使用了!
* 匿名内部类
匿名内部类属于特殊局部内部类,存在方法中的,并且只有类体,没有名字和任何修饰!
* 接口创建对象
```java
package cn.bjpowernode.javase01.day15.inner05;
public interface AnimalDao {
void eat();
}
package cn.bjpowernode.javase01.day15.inner05;
public class Test {
public static void main(String[] args) {
AnimalDao dao = new AnimalDao()
//匿名内部类,还是AnimalDao的实现类!
{
@Override
public void eat() {
System.out.println("猫吃鱼。。。");
}
};
dao.eat();
}
}
- 抽象类创建对象
package cn.bjpowernode.javase01.day15.inner06;
public abstract class Animal {
public abstract void eat();
}
package cn.bjpowernode.javase01.day15.inner06;
public class TestAnimal {
public static void main(String[] args) {
Animal a1 = new Animal()
{
@Override
public void eat() {
System.out.println("狗吃骨头。。。");
}
};
a1.eat();
}
}