面向对象
1. 类和对象
-
类 : 具有相同属性和行为的对象的集合。
-
对象:具有明确属性和行为的具体的实体。
-
类的语法
访问修饰符 class 类名{ //属性(全局变量、实例变量、成员变量) //行为 }
-
行为(方法)的语法
访问修饰符 返回类型 方法名(数据类型 参数名,数据类型2 参数名2){ 方法体; [return 值;] }
-
对象: new 就是一个对象
new 类名(xxx);
-
属性操作
- 赋值 对象.属性=值;
- 取值 对象.属性;
- 方法操作
调用 对象.方法();
1.1. 全局变量
-
定义在类下面的变量称为全局变,也称为全局变量、实例变量、成员变量和属性
-
语法
访问修饰符 数据类型 变量名;
-
全局变量会自动初始化
-
值类型默认的初始化
byte 0 short 0 int 0 long 0L float 0.0F double 0.0D boolean false char '\u0000'(空)
-
引用类型初始化全为null
1.2. 局部变量
-
定义在方法中的变量或方法参数中为局部变量
-
语法 : 注没有访问修饰符
数据类型 变量名;
-
局部变量必须手动初始化
1.3. 全局变量与局部变量的区别?
- 相同点
- 必须先声明再使用
- 在使用之前都要初始化
- 同一个作用域里的变量名不能重复,但不同作用域变量名可以重复
- 不同点
- 全局变量在类的下面,局部变量在方法参数中或方法块中
- 全局变量可以访问修饰符,局部变量不能有访问修饰符
- 全局变量会自动初始化,局部变量必须手动初始化
1.4. 方法,即类的行为
1.4.1. 语法
访问修饰符 返回类型 方法名(参数列表){
方法体;
}
1.4.2. 方法如何访问
-
main方法,切记只能让JVM调用,作为 程序的入口
-
自定义的方法调用即可
- 方法调用:
- 返回类型 变量=对象.方法(xxx);
- 注:
- 调用的时候,参数的类型、个数和顺序都必须一致
- 方法调用:
-
方法调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kmsLMXC2-1610499027897)(img/21.png)]
-
带返回值的方法调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFXbfpkR-1610499027899)(img/22.png)]
1.4.3. 方法重载
-
在同一个类下
-
方法名一样
-
参数的类型、个数和‘顺序’至少有一个不一样
void show(){} void show(int i){} void show(int i,String j){} void show(String,int i){} void show(int i,int j){} void show(int j,int i){} //类型一样,换不了顺序
###1.4.4. 形参与实参
- 声明时的参数为形式参数,简称形参
- 调用时的参数为实际参数,简称实参
1.5. 参数的传递
-
值传递: 参数的类型为值类型时,则为值传递。值传递,传递的是值复本。
-
引用传递: 参数的类型为引用类型时,则为引用传递。引用传递,传递的是引用的复本。
-
两者区别:
- 值传递,在方法里改变值,之前的值不会改变
- 引用传递,在方法里改变值,之前的值会发生改变。但String、StringBufferer、StringBuilder和枚举除外。
-
示例
/** * 值传递1 */ public class ValueTransferDemo2 { public static void main(String[] args) { int num=10; System.out.println(num); //10 new ValueTransferDemo2().change(num); System.out.println(num); //10 } public void change(int num) { num=100; } }
class Person{ int num = 10; } /** * 值传递2 */ public class ValueTransferDemo { public static void main(String[] args) { Person person = new Person(); System.out.println(person.num); //10 new ValueTransferDemo().change(person.num); System.out.println(person.num); //10 } public void change(int num) { num=100; } }
class Student{ int num = 10; } /** * 引用传递 * */ public class ReferTransferDemo { public static void main(String[] args) { Student stu = new Student(); System.out.println(stu.num); //10 new ReferTransferDemo().change(stu); System.out.println(stu.num); //100 } public void change(Student stu) { stu.num=100; } }
-
流程分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o4N9uIJC-1610499027901)(img/23.png)]
1.6. 构造方法
1.6.1. 特征
- 没有返回类型
- 方法名与类名一致
###1.6.2. 作用
- 创建对象
- 实例化一个类,首先调用类的对应的构造方法。当类中没有任意构造方法,JVM会自动创建空的构造方法(空参和空实现)。一但类的有了任意的构造方法,则JVM不会再自动的创建任意形式的构造方法。
- 初始成员变量
1.6.3. 其它
- 构造方法调用时也要保证参数的类型、个数和顺序要一致
- 构行方法也可以有方法重载
1.7.this
- 代表当前类的对象
2. 面向对象三大特征
2.1. 封装 : 安全性
-
体现:把属性私有化,通过公共的get/set或is/set进行公开出去,以后通过方法对属性进行操作。这样做的好处,是在方法中可以对属性的安全性和有效性作出验证。
-
示例:
class Student { //private,当前类中访问 private int age; private boolean handsome;//setXxx()和isXxx() public void setHandsome(boolean handsome) { this.handsome=handsome; } public boolean isHandsome() { return this.handsome; } //把属性通过public 的getXxx()和setXxx()方法公开出去 public void setAge(int age) { //验证 if(age>107) { age=107; }else if(age<1) { age=1; } this.age=age; } public int getAge() { return this.age; } } /** * 封装 * */ public class Demo { public static void main(String[] args) { Student stu1 = new Student(); stu1.setAge(2134567890); System.out.println(stu1.getAge()); Student stu2 = new Student(); stu2.setAge(-2134567890); System.out.println(stu2.getAge()); Student stu3 = new Student(); stu3.setAge(18); System.out.println(stu3.getAge()); } }
2.2. 继承 : 重用性、扩展性
2.2.1. 满足is a的关系
2.2.2. 用到extends关键字
2.2.3. 子类能继承父类中非私有的属性和方法
2.2.4. 方法重写
- 父子类
- 方法名相同,参数列表相同
- 子类的访问修饰符>=父类
- 子类返回类型<=父类(<=指是父子类)
- 子类抛的异常<=父类(<=指是父子类)
2.2.5. @Override
- 表示此方法重写了父类中的方法
2.2.6. 调用构造方法的顺序
- 实例化一个子类,首先调用父类空的构造方法,再调用子类对应的构造方法; 除非子类构造方法第一行有了super(xxx),则先调用父类对应的构造方法,再调子类对应的构造方法。
2.2.7. super关键字
- this: 代表当前类的对象
- super: 代表当前类的父类对象
2.2.8. 在java中的类是单继承
###2.2.9. 任何类的祖类都是Object,可以省略 extends Object
- Object类中常用的方法
- Object clone() : 克隆。protected它r指的是在同一个包,或不同包子类中能访问
- boolean equals(Object) : 地址相等
- void finalize() : 垃圾回收器调用此方法来回收对象所占空间。protected
- Class getClass() :得到Class对象
- int hasCode() :对象的哈希码。同个对象的哈唏码一致。
- String toString() :把对象用字符串输。一般我们自定义的类都会重写此方法。
- void wait() :线程所用方法,后面讲
- void notify() :线程所用方法,后面讲
- void notifyAll() :线程所用方法,后面讲
Dog d = new Dog("来福");
System.out.println(d.getName());
//1.clone()
Dog d2= (Dog) d.myClone();
System.out.println(d2.getName());
/**
* ==
* 值类型中表示值相等
* 引用类型中表示地址相等
* equals
* Object中表示地址相等
* */
//2.equals()
Dog d3= new Dog("来福");
Dog d4= new Dog("来福");
System.out.println(d3==d4); //false
System.out.println(d3.equals(d4)); //false
//3.finalize(); 让垃圾回收器来回收此对象,但不是立马,也不能保证时间
Dog d5= new Dog("来福");
d5.myFinalize();
//4. class();返回运行时字节码对象
Class clazz1= Dog.class;
Class clazz2 =d5.getClass();
System.out.println(clazz1 ==clazz2);//true
//5. hasCode();返回对象的哈希码
System.out.println(d3.hashCode()==d4.hashCode());//false
//6. toString(); 把对象变成字符串
System.out.println(d3.toString()); //打印出来的类型,一定为字符串
//7. wait() notify() notifyAll() 这在线程中进行讲解
2.3. 多态: 维护性、扩展性
- 口诀:
- 父类引用指向父类实例,只能调用父类的属性和方法
- 子类引用指向子类实例,可以调用父类中非私有的属性和方法
- 父类引用指向子类实例,只能调用父类的属性和方法,但是方法被子类重写,以子类的实现为准。
- 开闭原则
- 对扩展开放
- 对修改关闭
3. 访问修饰符
- private 同一个类
- default 同一个包
- protected 同一个包+不同包子类
- public 所有包
- 注:访问修饰符最低原则,为了安全性
3.1. 类有两个
- public 所有类
- default 同一个包
3.2. 方法和属性有四个
- private 同一个类
- default 同一个包
- protected 同一个包+不同包子类
- public 所有包
3.3. 示例
-
Demo1.java
package net.wanho.access.a; class Student{ } public class Demo1 { private int id; String name; protected int age; public String gender; public static void main(String[] args) { Demo1 d1 = new Demo1(); Student s1 = new Student(); d1.id=1001; d1.name="张三"; d1.age=18; d1.gender="男"; } }
-
Demo2.java
package net.wanho.access.a; public class Demo2 { public static void main(String[] args) { Demo1 d1 = new Demo1(); Student s1 = new Student(); //d1.id=1001; d1.name="张三"; d1.age=18; d1.gender="男"; } }
-
Demo3.java
package net.wanho.access.b; import net.wanho.access.a.*; public class Demo3 { public static void main(String[] args) { Demo1 d1 = new Demo1(); d1.gender="男"; } }
-
Demo4.java
package net.wanho.access.b; import net.wanho.access.a.Demo1; public class Demo4 extends Demo1 { public void show() { this.age=18; } public static void main(String[] args) { Demo4 d4 = new Demo4(); d4.age=18; d4.gender="男"; } }
4. this和super关键字
-
this代表当前类的对象
- this() 调用当前类的构造方法,必须放置在构造方法的第一行
- this.方法(); 调用当前类的普通方法,可以放置在任意行
-
super代表当前类的父类对象
- super() 调用当前类父类的构造方法,必须放置在子类构造方法的第一行
- super.方法() 高用当前父类的普通方法,可以放置在子类任意方法中的任意行
-
示例
Super.java
public class Super { private String name; public Super() { System.out.println("父类空的构造方法"); } public Super(String name) { this.name=name; System.out.println("父类带参的构造方法"); } public void show() { System.out.println("父类的普通方法:show()"); } }
Son.java
public class Son extends Super { public Son() { this("张三"); System.out.println("子类空的构造方法"); } public Son(String name) { super(name); System.out.println("子类带参的构造方法"); } @Override public void show() { System.out.println("子类的普通方法:show"); super.show(); this.sonOther(); } public void sonOther() { System.out.println("子类其它方法...."); } public static void main(String[] args) { new Son().show(); //父类带参的构造方法 //子类带参的构造方法 //子类空的构造方法 //子类的普通方法:show //父类的普通方法:show() //子类其它方法... } }
5. 抽象 abstract
5.1. 特征
- 修饰方法,即为抽象方法,且抽象方法没有方法体
- 修饰类,即为抽象类。一个类中有了抽象方法,这个类必须是抽象类;反之不然
- 子类继承于抽象类,必须要实现父类中的抽象方法,除非子类也是抽象类
- 抽象类中可以有实现的方法,也可以有抽象方法,还可以包含属性
- 抽象为不能被实例化
- 修饰抽象的关键字为abstract
5.2. 什么时候用抽象方法
- 当方法体不知该如何实现时,把此方法改变抽象方法
5.3. 为什么要用抽象方法
- 强制非抽象子类来实现此抽象方法。
6. static 静态
6.1. 修饰变量 : 静态变量(类变量)
- 数据共享
6.2. 修饰方法: 静态方法(类方法)
- 在同一个类中
- 普通方法可以直接访问普通方法,普通方法也可以直接访问静态方法。(main方法不允许自己调用 ,一般交由JVM调用 )
- 静态方法可以直接访问静态方法,静态方法可以通对象. 的方式访问普通方法。
- 在其它类中
- 类.静态方法()
- 对象.普通方法()
6.3. 如何访问
- 静态的内容,可以通
对象.
的方式进行方式,也可以通过类. 的方式进行访问,推荐后面一个 - 正因为静态内容,是通类. 的方式直接访问的,所以也称为类变量或类方法
7. final 最终
7.1. 修饰类
- 最终类,没有子类
7.2. 修饰方法
- 最终方法,此方法不能被子类重写
7.3. 修饰变量
- 常量:值固定不变的量
- 在声明的时候必须手动初始化
- 常量的值是放置在常量区
- 常量一但赋值后,就不能改变,即使改变的值跟之前一值,也不行
- 常量名一般为全大写
- 用途
- 为了统一消息提示,可以将提示的内容定义成常量
- 系统中的过程状态可以用常量进行声明
8. 接口 interface
-
接口不类,它是与类平级一种引用类型
-
语法
访问修饰符 interface 接口名{ 公共静态常量; 公共抽象方法; }
-
接口里可以包含
- 公共静态常量;
- 在声明常量必须手动初始化
- 常量名一般为全大写
- public static final 可以省略,也可以手动添加
- int NUM =10 ; 即为 public static final int NUM=10;
- 公共抽象方法;
- public abstract可以省略,也可以手动添加
- void show(); 即为 public abstract void show();
- public abstract可以省略,也可以手动添加
- 公共静态常量;
-
接口里只有一个种访问修饰,即为public,不加默认也为public
-
子类 多实现(implements) 接口,多个接口用逗号隔开;子类单继承父类
-
子类实现接口,要实现接口中抽象方法,除非子类是抽象类
-
接口与接口之间是多继承的关系
-
接口不能被实例化
9. 抽象类与接口有什么区别 ?
- 相同点:
- 都可以有静态常量
- 都可以有抽象方法
- 都不能被实例化
- 区别点:
- 抽象类中有属性、实现的方法、抽象方法等,但接口中只公共静态学量、公共抽象方法
- 抽象类中的访问修饰符有四种,但接口中只有一种
- 子类单继承抽象类,子类多实现接口,接口多继承接口
- 使用时机
- 当所有方法都不知道如何实现时,用接口。一般用标准的制订(方法功能描述)
- 当有些方法知道如何实现,有些不知道时,使用抽象。
- 示例
- 数据访问实现
- 使用接口制订数据访问方法的标签
- 使用抽象类 实现接口,实现其中公共代码。(已知如何实现),未知实现(不清楚具体数据)写成抽象方法。
- 使用MySQL数据类 继承 抽象类,实现抽象方法。(已知用MySQL数据库实例 )
- 使用Oralce数据类 继承 抽象类,实现抽象方法。(已知用Oralce数据库实例 )
- 数据访问实现
10. 包装类
-
只有值类型才有包装类
-
值类型与其对应的包装类型之间可以相互自动转换
-
对应关系
-
值类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
-
-
装箱 : 值类型赋值给其对应的包装类型
-
拆箱 : 包装类型赋值给其对应的值类型
11. java中代码顺序
-
类中所有代码执行的顺序 : 静态变量|静态代码块>普通变量|代码块>构造方法>普通方法
-
如果创建类的多个对象,静态的内容只初始化一次
public class SequenceDemo {
static int count = initCount();
int num = initNum();
private static int initCount() {
System.out.println("1静态变量"); //1
return 0;
}
static {
// 静态代码块
System.out.println("2静态代码块"); //2
}
private int initNum() {
System.out.println("3普通变量"); //3
return 10;
}
{
// 代码块
System.out.println("4普通代码块"); //4
}
public SequenceDemo() {
System.out.println("5空的构造方法"); //5构造方法
}
public static void main(String[] args) {
new SequenceDemo(); //12345
new SequenceDemo(); //345
}
}
15. 作业
填空题
- Java中有两种类型的选择结构的控制语句,分别是
__if____
语句和____switch-case_______
。 - 在Java JDK1.7之前,switch只能支持
_ byte short int char 和枚举_______________
类型。在JDK1.7中又加入了___string______
类型。 - for循环的语法格式是
_for(初始化;条件;趋于条件结束的语句){ }______________
,其中在整个循环过程中只执行一次的部分是___初始化________
。 - 在循环结构中,如果想跳出循环体,结束整个循环结构可以使用
_____break________
语句。 ____continue__________
语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。即只结束本次循环,而不是终止整个循环的执行。
选择题
1.以下代码的执行结果是( B )。(选择一项)
boolean m = true;
if(m = false){
System.out.println("false");
}else{
System.out.println("true");
}
A.false
B.true
C.编译错误
D.无结果
2.分析如下Java代码,编译运行的输出结果是(A )。(选择一项)
public static void main(String[ ] args) {
boolean a=true;
boolean b=false;
if (!(a&&b)) {
System.out.print("!(a&&b)");
}else if (!(a||b)) {
System.out.println("!(a||b)");
}else {
System.out.println("ab");
}
}
A!(a&&b)
B.!(a||b)
C.ab
D.!(a||b)ab
3.下列选项中关于变量x的定义,( BD )可使以下switch语句编译通过。(选择二项)
switch(x) {
case 100 :
System.out.println("One hundred");
break;
case 200 :
System.out.println("Two hundred");
break;
case 300 :
System.out.println( "Three hundred");
break;
default :
System.out.println( "default");
}
A.double x = 100;
B.char x = 100;
C.String x = "100";
D.int x = 100;
4.阅读下列文件定入的Java代码,其执行结果是( d )。
public class Test {
public static void main(String[] args) {
char ch = 'c';
switch (ch) {
case 'a':
System.out.print("a"); break;
case 'b':
System.out.print("ab");
case 'c':
System.out.print("c");
default:
System.out.print("d");
}
}
}
A.a
B.b
C.c
D.cd
5.以下Java程序编译运行后的输出结果是( B )。(选择一项)
public class Test {
public static void main(String[] args) {
int i = 0, sum = 0;
while (i <= 10) {
sum += i;//sum=sum+i
i++;
}
System.out.println(sum);
}
}
A.0
B.55
C.50
D.36
判断题
- if语句的条件表达式的结果都必须是boolean值。(对 )
- switch选择语句是多分支选择语句,只能处理等值条件判断的情况,表达式可以是int类型、char类型,但不能是double,float类型。( 对 )
- while循环结构的特点是先循环再判断,循环体至少执行一次。( 错 )
- for循环的语法格式是for (表达式1;表达式2;表达式3) {循环体},其中三个表达式都可以省略。( 对 )
- break语句可以出现在switch语句和循环语句中。( 对)
- continue语句可以出现在switch语句和循环语句中。( 错 )
简答题
-
if多分支语句和switch语句的异同之处
-
while和do-while语句的异同之处
-
break和continue语句的作用
##编程题
- 累加(1+2+…+100)
- 阶乘(
1*2*...*10
) - 开发一个标题为“ FlipFlop”的游戏应用程序。它从 1 计数到100 ,遇到3的倍数输出单词“ Flip”,遇到5的倍数就输出单词“Flop”,遇到即使 3 又是 5 的倍数时则输出单词“ FlipFlop” ,其余情况下输出当前数字。
4 . 可以从控制台连续输入数字,当输入的数字为0时不可以再输入
- 任意输入一个整数(小于10位),计算所有位的数字的和。12345–>15
6 . 判断回文 1235321
-
菲波拉锲数(1 1 2 3 5 8 )
-
根据成绩输出对应的等级,使用if多分支和switch语句分别实现。
a) A级 [90,100]b) B级 [80,89)
c) C级 [70,79)
d) D级 [60,69)
e) E级 [0,59)
-
定一个学生类
Student(id,name,age,gender,address)
从键盘输入一个班5个学生的信息,求和并输出年龄