面向对象基础——尚硅谷学习笔记

前言

学习面向对象的三条主线
1、java类及类的成员:属性、方法、构造器
2、面向对象的三大特征:封装、继承、多态、(抽象性)
3、其他关键字:
this、super、static、final、abstract、interface、package、import


概述

面向对象的编程思想基本上可以理解为面向对象的规则。面向过程和面向对象都是一种思想。(有一句话,万事万物皆对象,主要看自己的理解)

比如说:“把大象装进冰箱”
面向过程,强调功能性为,以函数为最小单位,考虑怎么做。(执行)
1、把冰箱门打开
2、抬起大象,塞进冰箱
3、把冰箱门关上

面向过程,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做(指挥)

{
    
    
	打开(冰箱){
    
    
		冰箱.开开();
	}
	抬起(大象){
    
    
		大象.进入(冰箱);
	}
	关闭(冰箱){
    
    
		冰箱 .闭合();
		}
}
冰箱{
    
    
	开开(){
    
    }
	闭合(){
    
    }
}
大象{
    
    
	进入(冰箱){
    
    }
}

程序员从面向过程的执行者转化成了面向对象的指挥者

面向对象分析问题的思路和步骤

一>根据问题需要,选择问题所针对的现实世界中的实体
一>从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
一>把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类造成计算机能够识别和处理的数据结构。
一>将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。


面向对象的两个要素(类和对象)

说明:
类:对一类事物的描述,是抽象的、概念上的定义
对象:是实际存在的该类事务的每个个体,因而也成为了实例(instance),(可以理解为对象是类的实例化,例如人Person是类,创建了一个对象,new了一个Tom,就是一个对象)
1、面向对象程序设计的重点是类的设计
2、设计类就是设计类的成员

(一)设计类就是设计类的成员
java代码世界是由诸多个不同功能的类构成的

专有名词的不同说法

  • 属性 = 成员变量 = field = 域、字段
  • 方法 = 成员方法 = 函数 = method
  • 创建类的对象 = 类的实例化 =实例化类

(二)类和对象的使用(面向对象思想落地的实现)(雷和对象的创建和执行操作分为三步)
1、创建类,设计类的成员 (主要在这一步)
2、创建类的对象
3、通过“对象.属性”或“对象.方法”调用对象的结构

示例
//测试类
public class PersonTest{
    
    
	public static void main(String[] args){
    
    
		//创建Person类对象
		Person p1 = new Person();
		//Scanner scanner = new Scanner();

		//调用对象的结构:属性、方法
		//调用属性:“对象.属性”
		p1.name = "Tom";
		p1.isMale = true;
		System.out.println(p1.name);

		//
		p1.eat();
		p1.sleep();
		p1.talk("Chinese");
	}
}
class Person{
    
    
	//属性
	String name;
	int age = 1;
	boolean isMale;
	
	//方法
	public void eat(){
    
    
		System.out.println("人可以吃饭"); 
	}
	public void sleep(){
    
    
		System.out.println("可以睡觉"); 
	}
	public void talk(String language){
    
    
		System.out.println("汉语"); 
	}
}


(三)如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
将p1变量保存的对象地址付给p3,导致p1和p3指向了对空间的同一个对象实体。
对象的属性未赋值时,该属性有默认初始化值。

(四)对象的内存解析
内存区域:方法区、虚拟机栈、本地方法栈、堆、程序计数器
堆:堆放对象实例
栈:指虚拟机栈。用于储存局部变量等
方法区:用于储存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

Person p1=p3;
//这里就不是创建新对象

类的结构

类的结构一:属性 类中属性的使用

属性(成员变量) vs 局部变量
1、相同点
1.1定义变量的格式: 数据类型 变量名 = 变量值
1.2先声明,后使用
1.3变量都有其对应的作用域
2、不同点:
2.1 在类中升不明的位置不同
属性:直接定义在类的一对{ }内
局部变量:将声明在方法内、方法形参、代码块内、构造器形参、构造器内的变量
2.2关于权限修饰符的不同
属性:可以再声明属性时,指明其权限,使用权限修饰符
常用的权限修饰符:private、public、缺省、protected -->封装性
目前,声明属性时,缺省
局部变量:不可以使用局部变量
2.3默认初始化值得情况
属性:类的属性,根据其类型,都有默认初始化值
整形(byte/short/int/long):0
浮点型(float/double):0.0
字符型(char):0(或‘\u0000’)
布尔型(boolean):false

引用数据类型(类、数组、接口):null

局部变量:没有默认初始化值
意味着:我们在调用局部变量之前,一定要先赋值
特别地:形参在调用时,我们赋值即可

2.4在内存中加载的位置
属性:加载到堆空间中(非static)
局部变量:加载到栈空间

示例
public class UserTest{
    
    
}
class User{
    
    
	//属性(或成员变量)
	String name;
	public int age;
	boolean isMale;

	public void talk(String language){
    
    //language:形参
		System.out.println("我们使用"+language+"进行交流");
	}
	public void eat(){
    
    
		String food = "烙饼";//局部变量
		System.out.println("北方人喜欢吃:"+food);
	}
}

类的结构二:方法 类中方法的声明和使用

方法:描述类应该具有的功能
比如:Math类:sqrt()\random()\……
Scanner类:nextXxx()……
Arrays类:sort()\binarySearch()\toString()\equals()\……

1、举例:
public void eat(){}
public void sleep(int hour){}
public String getName(){}
public String getNation(String nation){}
2、方法的声明:权限修饰符 返回值类型 方法名(形参列表(可有可无)){
方法体
}
注意:static、final、abstract 来修饰的方法,在后面讲
3、说明
3.1关于权限修饰符:
Java规定的4种权限修饰符:private、public、缺省、protected -->封装性以后再讲
3.2返回值类型: 有返回值 vs 无返回值
3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值得类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量。
如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不使用return 。但是如果使用,只能“return;”不跟数据,表示结束此方法的意思。
3.2.2我们定义方法是该不该有返回值?
①题目要求
②凭经验:具体问题具体分析
3.3方法名:属于标识符,遵循标识符的规则和规范“见名知意”
3.4形参列表:方法可以声明0个、1个、或者多个形参
3.4.1格式:数据类型1 形参1,数据类型2 形参2,……
3.4.2 我们定义方法时,该不该定义形参?
①题目要求
②凭经验:具体问题具体分析
3.5方法体:方法功能的体现
4、return关键字的使用:
4.1、使用范围:使用在方法中
4.2、作用:
①结束方法
②针对于有返回值类型的方法,使用“return数据”方法返回索要的数据。
4.3、注意点:return关键字后面不可以有执行语句
5、方法的使用中,可以调用当前类的属性和方法。方法里面可以再调方法。方法中不能再定义方法。
特殊的:方法A中又调用了方法A,这种方法叫递归方法。

public class CustomerTest{
    
    
	public static void main(String[] args){
    
    
		Customer cust1 = new Customer;
		cust1.eat();//如果eat方法是private的,在外面是无法调用的
	}
}
//客户类
class Customer{
    
    
	//属性(或成员变量)
	String name;
	public int age;
	boolean isMale;

	public void eat(){
    
    
		System.out.println("客户吃饭");
	}
	public void sleep(int hour){
    
    
		System.out.println("休息了"+hour+"小时");
	}
	public String getName(){
    
    
		return name;
		//return后不可声明表达式
	}
	public String getNation(String nation){
    
    
		String info = nation;
		return info;
	}
}

object类的使用

  1. object类是所有Java类的根父类
  2. 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
  3. Object类中的功能(属性、方法)就具有通用性。
object类toString方法的使用:
  1. 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
  2. Object类中toString()的定义:
    public String toString(){
    return getClass().getName() + “@” + Integer.toHexString(hashCode());
    }
  3. 像String、Date、File、包装类等都重写了Object类中的toString()方法。
    使得在调用对象的toString()时,返回“实体内容” 信息
  4. 自定义类也可以重写toString()方法,当调用此方法时,返回对象的“实体内容” 信息
== 和 equals() (面试题)

一、 = = 的使用
= = 运算符

  • 可以使用在基本数据类型变量和引用数据类型变量中
  • 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一定类型要相同)
    如果比较的是引用数据类型变量,比较两个对象的地址值是否相等,即两个引用是否指向同一个对象实体。
    补充:= = 符号使用时,必须保证符号左右两边的变量类型一致。
    二、equals()方法的使用:
  1. 是一个方法,而非运算符

  2. 只能适用于引用数据类型

  3. Object类中equals()的定义
    public Boolean equals(Object obj){
    return (this = = obj);
    }
    说明:Object类中定义的equals()和 == 的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象

  4. 像String、Date、File、包装类等都重写了Object类中的equals()的方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容”是否相同。

  5. 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的“实体内容”是否相同,那么我们就需要对Object类中的equals()进行重写。

重写equals()方法的原则

  • 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该是“true”
  • 自反性:x.equals(x)必须是“true”
  • 传递性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该是“true”
  • 一致性:如果x.equals(y)返回是“true”,只要x和y内容不变,不管重复调用几次equals()方法,返回都是“true”
    任何情况下,x.equals(null),永远返回“false”,null.equals(x)空指针异常,所以说使用equals()方法之前要先判断对象是否为空;x.equals(和x不同类型的对象)永远返回是“false”

包装类的使用

方法细节

一、方法的重载(load)

1、定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或类型不同即可。


“两同一不同”:同一个类、相同方法名
参数列表不同:参数个数不同,参数类型不同

2、举例:
Arrays类中重载的sort()/binarySearch()
3、判断是否是重载:
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系
4、在通过对象调用方法时,如何确定某个指定的方法:
方法名–>参数列表

二、可变形参的方法

1、jdk5.0新增的性能
2.具体使用
2.1 可变个数形参的格式:数据类型 … 变量名
2.2 当调用可变个数形参的方法时,传入形参的个数可以使:0个、1个…
2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组不构成重载,不可共存。
2.5 可变个数形参在方法的形参中,必须声明在形参列表的末尾。
2.6 可变个数形参的方法的形参中,最多只能声明一个可变形参。
示例

public class MethodArgsTest{
    
    
	public static void main(String[] args){
    
    
	MethodArgsTest test=new MethodArgsTest();
	test.show(12);
	test.show("hello");
	}
	public void show(int i){
    
    
	}
	//下面两个方法都可使用,如果同时出现且均可使用,优先会使用本方法
	public void show(String s){
    
    
		System.out.println("show(String)");
	}
	//
	public void show(String ... strs){
    
    
		System.out.println("show(String ... strs)");
	}

三、方法参数的值传递机制

关于变量的赋值
如果变量是基本数据类型,此时赋值的是变量所保存的数据值
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。

方法形参的传递机制:值传递
1、形参:方法定义时,声明的小括号内的参数
实参:方法调用时,实际传递给形参的数据
2、值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实储存的数据值(和C语言一样,传参后,会在存储空间开辟新的空间存储数值,形参改变后,不会改变实参的值)
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值(含变量的数据类型)。(相当于C语言中的传指针。)

四、递归方法的使用(了解)

1、递归方法:一个方法体内调用它自己。
2、方法递归包含了一种隐式的循环,他会重复执行某段代码,但这种重复执行无需循环控制。递归一定要向已知方向,否则这种递归就变成了无穷递归,类似于死循环。

类的结构之三:构造器(或构造方法、constructor)的使用

construct:建设、建造。construction:CCB constructor:建设者
构造器默认权限和类的权限是一样的

一、构造器的使用:

1、创建对象
创建类的对象:new + 构造器
2、初始化对象的信息

二、说明

1、如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
2、定义构造器的格式: 权限修饰符 类名(形参列表) 实参{ }
3、一个类中定义的多个构造器,彼此构成重载
4、一旦我们显式的定义了类的构造器之后,系统就不在提供默认的空参构造器
5、一个类中,至少会有一个构造器

总结:属性赋值的先后顺序
① 默认初始化值
② 显式初始化
③ 构造器中赋值//①②③都只能赋值一次

④ 通过“对象.方法”或“对象.属性”的方式赋值//④可以多吃赋值
以上操作的先后顺序: ①②③④


拓展

JavaBean

  • 是一种Java语言写成的可重用组件
  • 符合如下标准的Java类:
    • 类是公共的
    • 有一个无参的公共的构造器
    • 有属性,且有对应的get、set方法

UML类图

1、+ 表示public类型,-表示private类型,#表示protected类型
2、方法的写法:
方法的类型(+、-)方法名(参数名:参数类型):返回值类型

JVM内存结构

编译完源程序以后,生成一个或多个字节码文件
我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

推荐书籍:《JVM规范》

虚拟机栈

即为平时提到的栈结构。我们将局部变量存储在栈结构中。

我们将new出来的结构(比如:数组、对象)加载在空间中。补充:对象的属性(非static的)加载到堆空间中。

方法区

类的加载信息、常量池、静态域。


说明

一、理解万事万物皆对象

1.在Java语言范畴当中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构。

  • Scanner,String等
  • 文件:File
  • 网络地址:URL

2.涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。

二、内存解析的说明

引用类型的变量,只可能存储两类值:null 或者 地址值(含变量的类型)

三、匿名对象的使用

1、理解:我们创建的对象,没有显式地赋给一个变量名。即为匿名对象。
2、特征:匿名对象只能调用一次。
3、使用:开发中如何使用,可直接将匿名对象作为形参。例如p1.send(new mail);

面向对象的特征

面向对象的特征一:封装和隐藏

程序设计要求:尽可能 高内聚低耦合

高内聚:类的内部数据操作细节自己完成,不允许外部干涉
低耦合:仅对外暴露少量的方法用于使用。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用。从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

一、问题引入

当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。这里,赋值操作要收到属性的数据类型和存储范围的制约。除此之晚,没有其他限制条件。但是在实际问题中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时体现,我们只能通过方法进行限制条件的添加。
同时我们需要避免用户再使用“对象.属性”的方式对属性进行赋值。则需要将属性生命为私有的(private)

  • 此时针对于属性就体现了封装性

二、封装性的体现:

(不等同于封装性,这只是其中一个体现)
我们将类的属性Xxx私有化(private),同时,提供公共的(public)方法来获取(getXxx)和设置(setXxx)此属性的值

拓展
封装性的体现:
①如上 ②不对外暴露的私有的方法。③ 单例模式 ④ 如果不希望类在包外被调用,可以将类设置为缺省的

三、封装性的体现,需要权限修饰符的配合。

1、java规定的4种权限(从小到大排列):private、缺省、protected、public
2、4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
3、具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类

修饰类的话,只能使用
缺省、public

总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。

面向对象的特征二:继承性

一、继承性的好处

  1. 减少了代码的冗余,提高了代码的复用性
  2. 便于功能的扩展
  3. 为之后多态性的使用,提供了前提

继承性的格式:class A extends B{}

  • A:子类、派生类、subclass
  • B:父类、超类、基类、superclass

2.1 体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性、方法

  • 特别地,父类中生命为private的属性或方法,子类继承父类后,仍然认为获取了父类中私有的结构。只是因为封装性的影响,使得子类不能直接调用父类的结构而已。
    2.2 子类继承父类后,还可以声明自己特有的属性或方法,实现功能的扩展。
    子类和父类的关系,不同于子集和集合的关系。
    extends:延展、拓展

三、Java中关于继承性的规定

  1. 一个类可以被多个子类继承
  2. Java中类的单继承性:一个类只能有一个父类
  3. 子父类是相对的概念。
  4. 子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
  5. 子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法。

四、

  1. 如果我们没有显式的声明一个类的父类的话,则此类继承与java.lang.Object类
  2. 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
  3. 意味着,所有的java类具有java.lang.Object类声明的功能

五、方法的重写

override/overwrite

  1. 重写:子类继承父类后,可以对父类中同名同参数的方法,进行覆盖操作
  2. 应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的时子类重写父类的方法。
  3. 重写的规定:
    方法的声明:权限修饰符 返回值类型 方法名(形参列表){
    //方法体
    }
    约定俗称:子类中叫重写的方法,父类中叫被重写的方法。
    ①子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同。
    ②子类重写的方法的权限修饰符不小于父类的被重写的方法的权限修饰符。
  • 特殊情况:子类不能重写父类中声明为private权限的方法(因为子类看不到,重写后会被认为是新的方法)
    ③返回值类型:
  • 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
  • 父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以使A类或A类的子类
  • 父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(比如:必须也是double)。
    ④子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型。(具体查看异常处理部分)
说明
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)(静态方法不能被覆盖)

面向对象的特征三:多态性

  1. 理解多态性:可以理解为一个事务的多种形态。

  2. 何为多态性:
    对象的多态性:父类的引用指向子类的对象(或者子类的对象赋给父类的引用)

  3. 多态的使用:虚拟方法调用。
    有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
    总结:编译看左边;运行看右边。

  4. 多态性的使用前提:①类的继承关系;②方法的重写

  5. 对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

  6. 若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中。编译看左边,运行看右边。

  7. 对于实例变量则不存在这样的现象,即时子类里定义了与父类完全相同的实例变量,这个变量依然不可能覆盖父类中定义的实例变量,编译运行都看左边。

小结
虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多数情况下,将此时父类的方法成为虚拟方法,父类根据赋给他的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

编译时类型和运行时类型
编译时 对象为父类,而方法的调用是在运行时确定的,所以调用的是子类的重写后的方法–动态绑定

多态父类不能调用子类所特有的方法属性;
有了对象的多态以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类特有的属性和方法不能调用。
如何才能调用子类特有的属性和方法?
向下转型,使用强制类型转换符。

使用强转时,可能出现ClassCastException的异常。

instanceof关键字的使用
a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false

使用情景:为了避免在向下转型时出现ClassCastException异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。

如果a instanceof A返回true,则a instanceof B也返回true。(其中,B类是A的父类。)

面试题
方法的重载和重写
1.定义细节
重载:构造器也可以被重载
方法的重写:子类继承父类后,可以对父类中方法进行覆盖
2.从编译和运行的角度来看:
重载是指允许存在多个同名方法,而这些方法的参数不同。编译期根据方法不同的参数列表,对同名方法的名称作修饰。对编译器而言,这些同名方法就成了不同的方法。他们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
所以对于重载而言,在方法调用之前,编译期就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”
而对于多态,只用等到方法调用的那一刻,解释运行器才会确定所要调用的具体的方法,这称为“晚绑定”或“动态绑定”。
引用Bruce Eckel的话“不要犯傻,如果他不是晚绑定,他就不是多态”
3.重载不表现为多态性,重写表现为多态。


关键字

关键字: this的使用

1、this可以用来修饰、调用:属性、方法;构造器
2、this修饰属性的方法:

this理解为
当前对象 或 当前正在创建的对象
  • 在类的方法当中,我们可以使用“this.属性”或“this.方法”的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略this。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。
  • 在类的方法当中,我们可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都选择省略this。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。
    3、this调用构造器
  • ①我们在类的构造器中,可以显示的使用this(形参列表)方式,调用本类中指定的其它构造器
  • ②构造器中不能通过this(形参列表)方式调用自己
  • ③如果一个类中有n个构造器,则最多有n-1构造器使用了this(形参列表)
  • ④规定,this(形参列表)必须生命在当前构造器的首行
  • ⑤构造器内部,最多只能声明一个this(形参列表),用来调用其他的构造器

super 关键字的使用

  1. super理解为:父类的
  2. super可以用来调用:属性、方法、构造器
  3. super的使用
  • 3.1我们可以在子类的方法或构造器中使用“super.属性”或“super.方法”的方式,显式的调用父类中生命的属性或方法。但是通常情况下,我们习惯省略“super.”
  • 3.2特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类声明的属性,则必须显式的使用过“super.属性”的方式,表明调用的是父类中声明的属性。
  • 3.3特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用“super.方法”的方式,表明调用的是父类中声明的方法。
  1. super调用构造器
  • 4.1 我们可以在子类的构造器中显式的使用“super(形参列表)”的方式,调用父类中声明的指定的构造器
  • 4.2“super(形参列表)”的使用,必须声明在子类构造器的首行!
  • 4.3我们在类的构造器中,针对“this(形参列表)”或“super(形参列表)”只能二选一,不能同时出现。
  • 4.4在构造器的首行,没有显式的声明“this(形参列表)”或“super(形参列表)”
  • 4.5 在类的多个构造器中,至少有一个类的构造器中使用了 “super(形参列表)” ,调用父类中的构造器

子类对象实例化的全过程

  1. 从结果上来看:(继承性)
    子类继承父类以后,就获取了父类中声明的属性或方法
    创建子类的对象,在堆空间中,就会加载所有父类中生命的属性。
  2. 从过程上来看:
    当我们通过子类的构造器创建子类对象是,我们一定会直接或间接的调用器父类的构造器,进而调用父类的父类的构造器,知道调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。

明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。

关键字:package、import的使用

一、package关键字的使用

  1. 为了更好地实现项目中类的管理,提供包的概念
  2. 使用package声明类或者接口所属的包,声明在源文件的首行
  3. 包,属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”
  4. 每“.”一次,就代表一层文件目录
    补充:同一个包下,不能命名同名的接口、类。
    不同包下,可以命名同名的接口、类。

拓展:MVC设计模式
MVC时常用的设计模式之一,将整个程序分为三个层次:(V)视图模型层,(C)控制器层,(M)数据模型层。这种将程序输入输出、数据处理,以及数据的展示分离开来的设计模式使程序结构变得灵活而且清晰,同时也描述了程序各个对象间的通信方式,降低了程序的耦合性。

二、import关键字的使用

import :导入

  1. 在源文件中显式的使用import结构导入指定包下的类、接口。
  2. 声明在包的声明和类的声明之间
  3. 如果需要导入对个结构,则并列写出即可
  4. 可以使用“xxx.*”的方式,表示可以导入xxx包下的所有结构
  5. 如果使用的类或接口时Java.lang包下定义的,则可以省略import结构
  6. 如果使用的类或接口是本包下定义的,则可以省略import结构
  7. 如果在源文件中,使用了不包下的同名的类,则必须至少有一个类需要以全类名的方式显示
  8. 如果使用“xxx.*”方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入该子包
  9. import static :导入指定类或接口中的静态结构:属性或方法。

# 测试 java中的JUnit单元测试 步骤: 1. 选中当前工程 -- 右键选择:bulid path --add libraries --JUnit4 -- 下一步 2.创建Java类,进行单元测试。 此时的Java类要求:①此类是public的②此类提供公共的无参的构造器

static关键字的使用
1.static:静态的
2.static可以用来修饰:属性、方法、代码块、内部类
3.使用static修饰属性:静态变量
3.1属性:按是否使用static修饰:又分为:静态属性VS非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象的非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量:我们创建的类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
3.2 static修饰属性的其他说明:
①静态变量随着类的加载而加载。可以通过“类.静态变量”的方式进行调用
②静态变量的加载要早于对象的创建。
③由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法取得静态域中。
④类无法调用实例变量。

类变量 实例变量
yes no
对象 yes yes

3.3静态属性举例:System.out;Math.PI;

4.使用static修饰方法:静态方法
①随着类的加载而加载,可以通过“类.方法”的方式进行调用

静态方法 非静态方法
yes no
对象 yes yes

③静态方法中只能调用静态的方法或属性。(生命周期一致)
非静态方法中,即可以调用非静态的方法或属性,也可以调用静态的方法或属性。
5.static注意点:
5.1在静态的方法内,不能使用this关键字、super关键字
5.2关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。

6.开发中,如何确定一个属性是否要声明为static的?
/> 操作静态属性 的方法,通常设置为static的
/>工具类中的方法,习惯上声明为static的,比如:Math、Arrays、Collections

软件使用

eclipse 快捷键

  1. 补全代码:alt + /
  2. 快速修复:ctrl + 1
  3. 批量导包:ctrl + shift + o
  4. 使用单行注释: ctrl + /
  5. 使用多行注释: ctrl + shift +/
  6. 取消多行注释: ctrl + shift + \
  7. 复制指定的代码:ctrl + alt +down 或 ctrl + alt + up
  8. 删除指定代码: ctrl + d
  9. 上下移动代码:alt + up 或alt + down
  10. 切换到下一行代码:shift + enter
  11. 切换到上一行代码:ctrl+shift + enter
  12. 如何查看源码:ctrl + 选中指定结构 或 ctrl+shift +t
  13. 退回到前一个编辑的页面 : alt + left
  14. 进入到下一个编辑的页面(针对13条来说) : alt + right
  15. 光标选中指定的类,查看继承树结构:ctrl + t
  16. 复制代码: ctrl+c
  17. 撤销: ctrl + z
  18. 反撤销:ctrl + y
  19. 剪切: ctrl + x
  20. 粘贴:ctrl + v
  21. 保存: ctrl + s
  22. 全选: ctrl + a
  23. 格式化代码:ctrl + shift + f
  24. 选中数行,整体后移:tab
  25. 选中数行,整体前移:shift + tab
  26. 在当前类中,显示类结构,并支持搜索指定的方法属性等:ctrl + o
  27. 批量修改指定的变量名、方法名、类名等:alt + shift + r
  28. 选中的结构的大小写切换,变成大写:ctrl + shift + x
  29. 选中的结构的大小写切换,变成小写:ctrl + shift + y
  30. 调出生成getter/setter/构造器等结构:alt + shift + s
  31. 显示当前选择资源(工程or文件)的属性:alt + enter
  32. 快速查找:ctrl + k
  33. 关闭当前窗口:ctrl + w
  34. 关闭所有的窗口:ctrl + shift + w
  35. 查看指定的结构使用过的地方:ctrl + alt + g
  36. 查找与替换:ctrl + f
  37. 最大化当前的View:ctrl + m(双击也可)
  38. 直接定位到当前行的首位:home
  39. 直接定位到当前行的末尾:end

eclipse debug的使用

如何调试程序:
1、加入输入语句。System.out.println();
2、Eclipse Debug调试

  1. 设置断点(双击)
  2. step over 跳过(f6)执行完当前行的语句,进入下一行
  3. step into跳入 (f5)进入当前所调用的方法中
  4. drop to frame 回到当前行所在方法的第一行
  5. step return (f7)指向挖您当前行所在的方法,进入下一行
  6. resume恢复 执行完当前行所在断点的所有代码,进入下一个断点,如果没有就结束
  7. Terminate 终止 停止JVM,后面的程序不会在执行。

猜你喜欢

转载自blog.csdn.net/G_Shengn/article/details/123065477