1.面向对象的三条主线:
java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类
面向对象的特征:封装、继承、多态(抽象)
其他关键字的使用:this、super、package、import、static、final、interface(接口)、abstract(抽象)等
2.面向过程和面向对象的区别
面向过程:pop,以函数为单位,是一种“执行者思维”,适合解决一些简单问题,代码扩展性差,后期维护难度大
面向对象:oop,以“类”为单位,每种事物都具备自己的属性和行为/功能。是一种“设计者思维”,适合解决复杂问题
代码扩展性强,可维护性高
二者关系:他们是相辅相成,面向对象离不开面向过程
3.面向对象编程两个核心概念:类(class)、对象(object)
对两个概念的理解:
类:具有相同特征的事物描述,是抽象的概念上的定义
对象:实际存在的该类事物的每个个体,是具体的,因而被称为实例
4.类的声明与使用
4.1体会:设计类就是设计类的成员
4.2类的内部成员:
成员一:属性、成员变量、field(字段、域)
成员二:(成员)方法、函数、method
4.2类的实例化
等价描述:类的实例化==创建类的对象==创建类的实例
格式:类的类型 对象名 = 通过new创建的对象实体
举例:Phone p1 = new Phone();
Scanner scan = new Scanner(System.in);
String str = new String();
5.面向对象完成的具体功能操作的三步流程(非常重要)
步骤1:创建类并设计类的内部成员(属性、方法)
步骤2:创建类的对象。使用new关键字
步骤3:通过对象调用其内部声明的属性或方法来完成相关的功能
package Oop.atguigu01;
/*
抽象
*/
public class Phone {
//属性
String name;//品牌
double price;//价格
//方法
public void call(){
System.out.println("手机能够拨打电话");
}
public void sendMessage(String message){
System.out.println("发送信息"+message);
}
public void playGame(){
System.out.println("手机可以玩游戏");
}
}
package Oop.atguigu01;
public class PhoneTest {//Phone测试类
public static void main(String[] args) {
//创建对象
Phone p1 = new Phone();
//通过Phone的对象,调用其内部声明的属性或方法
//格式:对象.属性 或 对象.方法
p1.name ="红米K50";
p1.price = 2599;
System.out.println("name="+p1.name+",price="+p1.price);
//调用方法
p1.call();
p1.sendMessage("有内鬼,终止交易");
p1.playGame();
}
}
类的成员变量之一:属性
类的成员之一:属性
1.变量的分类:
-角度一:按照数据类型来分:基本数据类型(八种)、引用数据类型(数组、类、接口、枚举、注解、记录)
-角度二:按照变量在类中声明的位置不同:成员变量(或属性)、局部变量(方法内、方法形参、构造器内、构造器形参、代码块内等)
2.属性的几个称谓:成员变量、属性、field(字段、域)
3.区分成员变量 vs 局部变量
3.1相同点:
1.变量声明的格式都相同:数据类型 变量名 = 变量值
2.变量都有其有效的作用域,出了作用域就失效了
变量必须先声明,后赋值,在使用
3.2不同点
3.2.1类中声明位置的不同;
属性:声明在类内,方法外的变量
局部变量:声明在方法、构造器内部的变量
3.2.2在内存中分配的位置不同(难点):
属性:随着对象的创建,存储在堆空间内
局部变量:存储在栈空间中
3.2.3生命周期:
属性:随着对象的创建而创建,随着对象的消亡而消亡
局部变量:随着方法对应的栈帧入栈,局部变量会在栈中分配,随着方法对应的栈帧出栈,局部变量消亡
3.2.4作用域
属性:在整个类的内部都有效
局部变量:仅限于声明此局部变量所在的方法(或构造器、代码块内)中
3.2.5是否可以有权限修饰符进行修饰
都有哪些权限修饰符:public、protected、缺省、private(用于表明所修饰的结构可调用的范围)
属性:属性可以使用权限修饰符进行修饰
局部变量:不能使用任何权限修饰符进行修饰
3.2.6是否有默认值(重点):
属性:都有默认初始化值
意味着,如果没有给属性进行显式初始化值,则会有默认初始化值
局部变量:都没有默认初始化值
在使用局部变量之前,必须要显式的赋值,否则或报错
注意:对于方法的形参而言,在调用方法是,给此形参赋值即可
package Oop.atguigu03_field_method.field;
public class FieldTest {
public static void main(String[] args) {
Person p1 = new Person();
System.out.println(p1.name+","+p1.age+","+p1.gender);
}
}
class Person{
//属性(或成员变量)
String name;
int age;
char gender;
//方法
public void eat(){
String food = "麻辣香锅";//局部变量
System.out.println("我喜欢吃"+food);
}
public void sleep(int hour){//形参:属于局部变量
System.out.println("人不能少于"+hour+"小时睡眠");
}
}
类的成员变量之二:方法
类的成员之二:方法(method)
1.使用方法的好处:
方法的理解:“方法”是对类或对象行为特征的抽象,用来完成某个功能操作
方法的好处:实现代码重用,减少冗余,简化代码
2.使用举例:
-Math.random()的random()方法
-Math.sqrt()的sqrt(x)方法 开方
-System.out.println()的println(x)方法
-Arrays类中的binarySearch()方法/sort()方法、equals()方法
3.声明举例:
public void eat()
public void sleep(int hour)
public String interests(String hobby)
public int getAge()
4.方法声明的格式:(重要)
权限修饰符 [其他修饰符] 返回值类型 方法名 [throws 异常类型](形参列表){//方法头或方法的声明
//方法体
}
注:[]中的内部不是必须
5.具体方法声明的细节:
5.1权限修饰符
1.可以使用哪些权限修饰符
四种:private \ 缺省 \ protected \ public
5.2返回值类型:描述当调用完此方法时,是否需要返回一个结果
分类:
>无返回值类型,使用void表示即可
>有具体的返回值类型,需要指明返回数据的类型,可以是基本数据类型,也可以是引用数据类型
需要在方法内部配合使用"return"+返回值的变量或者常量
5.3方法名:属于标识符。需要满足标识符的规定和规范。“见名思意”
5.4形参列表:形参,属于局部变量,且可以声明多个
格式:(形参类型1 形参1,形参类型2 形参2,...)
分类:无形参列表、有形参列表
>无形参列表不能省略小括号
>有形参列表:根据方法调用时,需要的不确定的变量的类型和个数,确定形参的类型和个数
5.5方法体:当调用一个方式时,真正执行的代码。体现了此方法的功能
6.注意点:
在Java中方法不能独立存在,所有方法必须定义在类里
Java中的方法不调用不执行,不执行,每调用一次,就执行一次
方法内可以调用本类的(其他)方法或属性
方法内不能定义方法
7.关键字 return
7.1 return的作用
作用1:结束一个方法
作用2:结束一个方法的同时,可以返回数据给方法的调用者(方法声明中如果有返回值类型,则方法内需要搭配return使用)
7.2使用注意点
return后面不能有声明执行语句
8.方法调用的内存解析:
形参:方法内声明时,一对()内声明的一个或者多个形式参数,简称为形参
实参:方法在被调用时实际传递给形参的变量或者常量称为实际参数,简称实参
package Oop.atguigu03_field_method.method.Exer2;
public class Employee2 {
int id=32;
String name="yyy";
int age=18;
double salary=30000.00;
public void show(){
System.out.println("编号:"+id+",姓名:"+name+",年龄:"+age+",薪资:"+salary);
}
}
package Oop.atguigu03_field_method.method.Exer2;
import com.sun.xml.internal.bind.v2.model.core.ID;
public class Test {
public static void main(String[] args) {
Employee2 p1 = new Employee2();
p1.show();
}
}
类的成员变量之三:构造器
类的成员变量三:构造器(constructor)、构造方法
1.构造器的理解
constructor:n 建设者、建造者
construct:v 建造、建设
construction:n 建造、建设
2.构造器的作用
作用1:搭配new关键字,创建类的对象(实例)
作用2:在创建对象的同时,可以给对象的相关属性赋值
3.构造器的使用说明
>构造器声明格式:权限修饰符 类名(形参列表){}
>创建类以后,在没有显示提供任何构造器的情况下,系统会默认提供一个空参的构造器,且构造器的权限
与类声明的权限相同。
>一旦类中显示声明了构造器,则系统不再提供默认的空参构造器
>一个类中可以声明多个构造器,彼此之间构成重载。
package Oop.atguigu08_constructor;
public class Person {
String name;
int age;
//构造器
public Person(){
System.out.println("Person()...");
}
// //声明其他的构造器
public Person(int a){
age=a;
}
public void eat(){
System.out.println("人吃饭");
}
public void sleep(int hour){
System.out.println("每天至少睡"+hour+"小时");
}
}
package Oop.atguigu08_constructor;
public class PersonTest {
public static void main(String[] args) {
Person p1=new Person();
p1.eat();
}
}
方法的重载
方法的重载(overload):
1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们参数列表不同即可
满足这样特征的多个方法,彼此之间构成方法的重载
2.总结为:“两同一不同”
两同:同一个类、相同的方法
一不同:参数列表不同。
可以是参数个数不同
可以是参数类型不同
方法的重载注意:方法的重载与形参的名、权限修饰符、返回值类型都没有关系
3.举例
4.如何判断两个方法是否相同
方法名相同并且形参列表相同(形参列表相同指参数个数和类型都相同,与形参名没关系)
要求:在一个类中,允许存在多个相同名字的方法,只要他们的形参列表不同即可
编译器怎么确定调用的某个具体的方法
先通过方法名确定一波重载的方法,进而通过不同的形参确定某一个具体的方法
5.同一个类中不允许定义两个相同的方法。
package Oop.atguigu05_method_more._02args;
public class ArgsTest {
public static void main(String[] args) {
ArgsTest test = new ArgsTest();
test.print();
test.print(1);
test.print(1,2);
test.print(new int[]{1,2,3});
test.print(1,2,3);//效果同上
}
public void print(int... nums){
System.out.println("1111");
//遍历
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
public void print(int i){
System.out.println("2222");
}
public void print(int i,int j){
System.out.println("3333" );
}
}
递归方法
1.何为递归方法:方法自己调用自己的现象就叫递归。
2.递归方法的分类:直接递归、间接递归
3.使用说明:
1.递归方法包含了一种“隐式循环”。
2.递归方法会“重复执行”某段代码,但这种重复执行无需循环控制。
3.递归一定要向“已知方向”递归,否者这种递归会成为无穷递归,停不下来,类似死循环。最终发生“栈内存溢出”。
注意:
1.递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多是速度比循环‘慢得多’,所以使用递归方法要慎重
2.在要求高性能的情况下避免使用递归,递归调用即花时间又‘耗内存’。考虑使用循环迭代
package Oop.atguigu05_method_more._04recursion.exer1;
public class RecursionTest {
public static void main(String[] args) {
RecursionTest test = new RecursionTest();
// test.method1();
System.out.println(test.getSum1(100));
int n=5;
System.out.println(test.getMul(5));//120
}
/**
* 举例1:计算1-100内自然数的总和
*/
public int getsum(int num){
int sum=0;
for (int i = 1; i <= num; i++) {
sum+=i;
}
return sum;
}
/**
* 递归方法输出1-100自然数的和
* @param num
* @return
*/
public int getSum1(int num){
if(num==1){
return 1;
}else {
return getSum1(num-1)+num;
}
}
/**
* 举例2:计算n!
*/
public int getMul(int n){
if(n==1){
return 1;
}else{
return n*getMul(n-1);
}
}
/**
* 快速排序
*/
/**
* 举例4:汉塔诺游戏
*/
/**
* 举例5:斐波那契数列
* 1 1 2 3 5 8 ...
*
* f(n)=f(n-1)+f(n-2)
*/
public int f(int n){
if(n==1){
return 1;
}else{
return f(n-1)+f(n-2);
}
}
/**
* 举例6
* File类的对象表示一个文件目录
* 计算指定文件目录的大小,遍历指定的文件目录中的所有的文件。删除指定的文件目录
*/
/**
* 如下递归方法调用会导致StackOverflowError
*/
// public void method1(){
// System.out.println("method1()...");
// method1();
// }
}