首页 / JAVA / java基础学习(五)
java基础学习(五)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java基础学习(五),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含15390字,纯文字阅读大概需要22分钟。
内容图文
java基础学习(五)
十六、方法、类、对象、访问权限
十七、java继承和多态
十六、方法、类、对象、访问权限
-
同一个类中,一个方法调用另一个方法,如果对方不是static修饰,必须用对象调用,但是java允许省略不写,及可以省略this
-
static修饰的方法不能使用this关键字,也不能调用非static修饰的方法、变量
-
参数名和成员变量明相同时使用this关键字来代表
-
this()方法只能用在构造方法内,且必须是第一条语句,表示本类的构造方法
-
对象创建:
-
显示创建:
-
new创建
类名 对象名 = new 类名();
使用 new 关键字或 Class 对象的 newInstance() 方法创建对象时,都会调用类的构造方法
-
调用 java.lang.Class 或者 java.lang.reflect.Constuctor 类的 newlnstance() 实例方法
java.lang.Class Class 类对象名称 = java.lang.Class.forName(要实例化的类全称); 类名 对象名 = (类名)Class类对象名称.newInstance();
使用 Class 类的 newInstance() 方法创建对象时,会调用类的默认构造方法,即无参构造方法。
-
调用对象的 clone() 方法
类名对象名 = (类名)已创建好的类对象名.clone();
使用 Object 类的 clone() 方法创建对象时,不会调用类的构造方法,它会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但它们的属性值相同。
如果类没有实现 Cloneable 接口,则 clone。方法会抛出 java.lang.CloneNotSupportedException 异常,所以应该让类实现 Cloneable 接口。
-
-
隐式创建:
- 创建String对象
- 使用+号创建新的String对象
- java虚拟机加载一个类时,会隐式的创建描述该类的Class实例(类的加载是指把类的 .class 文件中的二进制数据读入内存中,把它存放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。)
-
无论釆用哪种方式创建对象,Java 虚拟机在创建一个对象时都包含以下步骤:
- 给对象分配内存。
- 将对象的实例变量自动初始化为其变量类型的默认值。
- 初始化对象,给实例变量赋予正确的初始值。
-
注意:每个对象都是相互独立的,在内存中占有独立的内存地址,并且每个对象都具有自己的生命周期,当一个对象的生命周期结束时,对象就变成了垃圾,由 Java 虚拟机自带的垃圾回收机制处理。
-
-
java匿名对象
-
一般匿名对象只使用一次,而且匿名对象只在堆内存中开辟空间,而不存在栈内存的引用。
-
public static void main(String[] args) { new Person("张三", 30).tell(); // 匿名对象 }
-
-
对象的销毁:
-
对象使用完之后需要对其进行清除。对象的清除是指释放对象占用的内存。在创建对象时,用户必须使用 new 操作符为对象分配内存。不过,在清除对象时,由系统自动进行内存回收,不需要用户额外处理。这也是 Java 语言的一大特色,某种程度上方便了程序员对内存的管理。
Java 语言的内存自动回收称为垃圾回收(Garbage Collection)机制,简称 GC。垃圾回收机制是指 JVM 用于释放那些不再使用的对象所占用的内存。
Java 语言并不要求 JVM 有 GC,也没有规定 GC 如何工作。不过常用的 JVM 都有 GC,而且大多数 GC 都使用类似的算法管理内存和执行回收操作。具体的垃圾回收实现策略有好多种,在此不再赘述。
一个对象被当作垃圾回收的情况主要如下两种。
1)对象的引用超过其作用范围。
{ Object o = new Object(); // 对象o的作用范围,超过这个范围对象将被视为垃圾 }
2)对象被赋值为 null。
{ Object o = new Object(); o = null; // 对象被赋值为null将被视为垃圾 }
在 Java 的 Object 类中还提供了一个 protected 类型的 finalize() 方法,因此任何 Java 类都可以覆盖这个方法,在这个方法中进行释放对象所占有的相关资源的操作。
在 Java 虚拟机的堆区,每个对象都可能处于以下三种状态之一。
1)可触及状态:当一个对象被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
2)可复活状态:当程序不再有任何引用变量引用该对象时,该对象就进入可复活状态。在这个状态下,垃圾回收器会准备释放它所占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的 finalize() 方法,这些 finalize() 方法有可能使该对象重新转到可触及状态。
3)不可触及状态:当 Java 虚拟机执行完所有可复活对象的 finalize() 方法后,如果这些方法都没有使该对象转到可触及状态,垃圾回收器才会真正回收它占用的内存。
注意:调用 System.gc() 或者 Runtime.gc() 方法也不能保证回收操作一定执行,它只是提高了 Java 垃圾回收器尽快回收垃圾的可能性。
-
-
访问控制符
-
private:同类
-
friendly:同包
-
protected:同包或异包子类
-
public:同包、异包
-
访问范围 private friendly(默认) protected public 同一个类 可访问 可访问 可访问 可访问 同一包中的其他类 不可访问 可访问 可访问 可访问 不同包中的子类 不可访问 不可访问 可访问 可访问 不同包中的非子类 不可访问 不可访问 不可访问 可访问
-
-
static关键字:
- 静态变量:从属于类,虚拟机加载类的时候分配内存,类内任意访问,类外类名访问
- 实例变量:从属于对象,虚拟机每次创建实例的时候分配内存,类内非静态方法都可访问,类外或类内静态方法需通过实例对象访问
- 静态方法:从属于类,不能调用非静态成员
- 实例方法:从属于对象,可以直接调用实例变量、实例方法、静态变量、静态方法
- 静态代码块:从属于类,虚拟机加载时执行一次,按顺序执行,不能调用非静态成员,不能存在方法体中
- 非静态代码块:从属于对象,代码域中定义的变量都是局部的,只有域中的代码可以调用
-
this关键字和super关键字都和类的特定实例相关
-
final关键字:
- 修饰变量:成为常量,必须赋值
- 局部常量:在使用前赋值
- 静态常量:在静态代码块中赋值或构造方法中赋值
- 成员常量:在静态代码块中赋值或构造方法中赋值
- 修饰对象:引用地址不变,但是对象本身可以变化
- 修饰方法:不能在子类中被重写,但是在本类中重载没问题
- 修饰类:不可被继承
- 修饰变量:成为常量,必须赋值
-
可变参数列表:
methodName({paramList},paramType…paramName)
中括号实际开发中不存在,只能有一个可变参数(同种类型的形式参数可以有任意多个),且只能放在最后
-
构造方法:无参数的构造方法也被称为 Nullary 构造方法。只有编译程序自动加入的构造方法,才称为默认构造函数。如果自行编写无参数、没有内容的构造函数,就不称为默认构造函数了(只是 Nullary 构造函数)。虽然只是名词定义,不过认证考试时要区别一下两者的不同。
-
析构方法:析构方法与构造方法相反,当对象脱离其作用域时(例如对象所在的方法已调用完毕),系统自动执行析构方法。析构方法往往用来做清理垃圾碎片的工作,例如在建立对象时用 new 开辟了一片内存空间,应退出前在析构方法中将其释放。
在 Java的 Object 类中还提供了一个 protected 类型的 finalize() 方法,因此任何 Java 类都可以覆盖这个方法,在这个方法中进行释放对象所占有的相关资源的操作。
对象的 finalize() 方法具有如下特点:
- 垃圾回收器是否会执行该方法以及何时执行该方法,都是不确定的。
- finalize() 方法有可能使用对象复活,使对象恢复到可触及状态。
- 垃圾回收器在执行 finalize() 方法时,如果出现异常,垃圾回收器不会报告异常,程序继续正常运行。
- 由于 finalize() 方法的不确定性,所以在程序中可以调用 System.gc() 或者 Runtime.gc() 方法提示垃圾回收器尽快执行垃圾回收操作
-
包:
-
Java 包的命名规则如下:
- 包名全部由小写字母(多个单词也全部小写)。
- 如果包名包含多个层次,每个层次用“.”分割。
- 包名一般由倒置的域名开头,比如 com.baidu,不要有 www。
- 自定义包不能 java 开头。
-
有冲突使用类全名
-
java常用系统包:
包 说明 java.lang Java 的核心类库,包含运行 Java 程序必不可少的系统类,如基本数据类型、基本数学函数、 字符串处理、异常处理和线程类等,系统默认加载这个包 java.io Java 语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等 java.util 包含如处理时间的 Date 类,处理动态数组的 Vector 类,以及 Stack 和 HashTable 类 java.awt 构建图形用户界面(GUI)的类库,低级绘图操作 Graphics 类、图形界面组件和布局管理 (如 Checkbox 类、Container 类、LayoutManger 接口等),以及用户界面交互控制和事 件响应(如 Event 类) java.awt.image 处理和操纵来自网上的图片的 Java 工具类库 java.wat.peer 很少在程序中直接用到,使得同一个 Java 程序在不同的软硬件平台上运行 java.net 实现网络功能的类库有 Socket 类、ServerSocket 类 java.lang.reflect 提供用于反射对象的工具 java.util.zip 实现文件压缩功能 java.awt.datatransfer 处理数据传输的工具类,包括剪贴板、字符串发送器等 java.sql 实现 JDBC 的类库 java.rmi 提供远程连接与载入的支持 java. security 提供安全性方面的有关支持
-
十七、java继承和多态
1. 封装:
- get、set方法,权限访问符
2. 继承:
-
public class Student extends Person{}
-
只能单继承,父类的private对子类不可见,子类会调用父类的构造方法
3. super关键字:
- super 关键字的功能:
- 在子类的构造方法中显式的调用父类构造方法,必须写在第一行
- 访问父类的成员方法和变量。
4. super 和 this 关键字的异同:
- 子类和父类中变量或方法名称相同时,用 super 关键字来访问。可以理解为 super 是指向自己父类对象的一个指针。在子类中调用父类的构造方法。
- this 是自身的一个对象,代表对象本身,可以理解为 this 是指向对象本身的一个指针。在同一个类中调用其它方法。
- this 和 super 不能同时出现在一个构造方法里面,因为 this 必然会调用其它的构造方法,其它的构造方法中肯定会有 super 语句的存在,所以在同一个构造方法里面有相同的语句,就失去了语句的意义,编译器也不会通过。
- this( ) 和 super( ) 都指的是对象,所以,均不可以在 static 环境中使用,包括 static 变量、static 方法和 static 语句块。
- 从本质上讲,this 是一个指向对象本身的指针, 然而 super 是一个 Java 关键字。
5. 向上转型、向下转型、静态绑定、动态绑定
-
通过引用类型变量来访问所引用对象的属性和方法时,Java 虚拟机将采用以下绑定规则:
- 实例方法与引用变量实际引用的对象的方法进行绑定,这种绑定属于动态绑定,因为是在运行时由 Java 虚拟机动态决定的。例如,animal.eat() 是将 eat() 方法与 Cat 类绑定。
- 静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为是在编译阶段已经做了绑定。例如,animal.staticEat() 是将 staticEat() 方法与 Animal 类进行绑定。
- 成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为在编译阶段已经做了绑定。例如,animal.name 和 animal.staticName 都是与 Animal 类进行绑定。
-
说白了,动态绑定只发生在,实例方法和引用变量实际引用的对象的方法之间,其他的都是静态绑定,都是父类的方法、变量。
-
向上转型:
fatherClass obj = new sonClass();
-
向下转型:
sonClass obj = (sonClass) fatherClass;
6. 重载
- 如果同一个类中包含了两个或两个以上方法名相同的方法,但形参列表不同,这种情况被称为方法重载(overload)。与方法返回值类型、修饰符等,与方法重载没有任何关系。
7. 重写
-
在子类中如果创建了一个与父类中相同名称、相同返回值类型、相同参数列表的方法,只是方法体中的实现不同,以实现不同于父类的功能,这种方式被称为方法重写(override),又称为方法覆盖。
-
在重写方法时,需要遵循下面的规则:
- 参数列表必须完全与被重写的方法参数列表相同。
- 返回的类型必须与被重写的方法的返回类型相同(Java1.5 版本之前返回值类型必须一样,之后的 Java 版本放宽了限制,返回值类型必须小于或者等于父类方法的返回值类型)。
- 访问权限不能比父类中被重写方法的访问权限更低(public>protected>default>private)。
- 重写方法一定不能抛出新的检査异常或者比被重写方法声明更加宽泛的检査型异常。例如,父类的一个方法声明了一个检査异常 IOException,在重写这个方法时就不能抛出 Exception,只能拋出 IOException 的子类异常,可以抛出非检査异常。
-
另外还要注意以下几条:
- 重写的方法可以使用 @Override 注解来标识。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。(这是final的定义)
- 声明为 static 的方法不能被重写,但是能够再次声明。(为了实现多态,所以不能对静态方法重写)
- 构造方法不能被重写。
- 子类和父类在同一个包中时,子类可以重写父类的所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中时,子类只能重写父类的声明为 public 和 protected 的非 final 方法。
- 如果不能继承一个方法,则不能重写这个方法。
8. 多态
-
多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。
对面向对象来说,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。
-
java实现多态有 3 个必要条件:继承、重写和向上转型
9. instanceof
-
在 Java 中可以使用 instanceof 关键字判断一个对象是否为一个类(或接口、抽象类、父类)的实例
-
boolean result = obj instanceof Class
-
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。class可以是类,可以是接口。
instanceof在Java的编译状态和运行状态是有区别的:
在编译状态中,class可以是object对象的父类,自身类,子类。在这三种情况下Java编译时不会报错。
在运行转态中,class可以是object对象的父类,自身类,不能是子类。在前两种情况下result的结果为true,最后一种为false。但是class为子类时编译不会报错。运行结果为false。 (大致就是判断表达式:class 变量=(class)object的引用 是否成立)。 -
object instanceof class中,object 是看它实际引用的对象。
10. 抽象类
-
如果一个类中没有包含足够的信息来描绘一个具体的对象,那么这样的类称为抽象类
-
<abstract>class<class_name> { <abstract><type><method_name>(parameter-iist); }
-
abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中
-
抽象类的定义和使用规则如下:
- 抽象类和抽象方法都要使用 abstract 关键字声明。
- 如果一个方法被声明为抽象的,那么这个类也必须声明为抽象的。而一个抽象类中,可以有 0~n 个抽象方法,以及 0~n 个具体方法。
- 抽象类不能实例化,也就是不能使用 new 关键字创建对象。
11. 接口
-
接口比抽象类更加抽象,因为其中的成员变量为全局静态常量,方法为公共抽象方法,都是public的
-
[public] interface interface_name [extends interface1_name[, interface2_name,…]] { // 接口体,其中可以包含定义常量和声明方法 [public] [static] [final] type constant_name = value; // 定义常量 [public] [abstract] returnType method_name(parameter_list); // 声明方法 }
-
一般不用声明public、static、final ,都是隐式的,不能实例化
-
所有的抽象方法必须被重写,否则新类要定义为抽象类
-
implements来实现接口,可以多实现,但只能单继承,继承在前,实现在后
12. 内部类
- 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的
.class
文件,但是前面冠以外部类的类名和$
符号。 - 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
- 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。
- 外部类只有两种访问级别:public 和默认;内部类则有 4 种访问级别:public、protected、 private 和默认。
- 在外部类中可以直接通过内部类的类名访问内部类。
-
实例内部类:
-
在外部类的静态方法和外部类以外的其他类中,必须通过外部类的实例创建内部类的实例。
-
Inner1 i = new Outer().new inner1();//实例化方法
-
在实例内部类中,可以访问外部类的所有成员。
-
在实例内部类中不能定义 static 成员,除非同时使用 final 和 static 修饰。
-
-
静态内部类:
- 在创建静态内部类的实例时,不需要创建外部类的实例。
- 静态内部类中可以定义静态成员和实例成员。外部类以外的其他类需要通过完整的类名访问静态内部类中的静态成员,如果要访问静态内部类中的实例成员,则需要通过静态内部类的实例。
- 静态内部类可以直接访问外部类的静态成员,如果要访问外部类的实例成员,则需要通过外部类的实例去访问。
-
局部内部类:
- 局部内部类是指在一个方法中定义的内部类
- 局部内部类与局部变量一样,不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。
- 局部内部类只在当前方法中有效。
- 局部内部类中不能定义 static 成员。
- 局部内部类中还可以包含内部类,但是这些内部类也不能使用访问控制修饰符(public、private 和 protected)和 static 修饰符修饰。
- 在局部内部类中可以访问外部类的所有成员。
- 在局部内部类中只可以访问当前方法中 final 类型的参数与变量。如果方法中的成员与外部类中的成员同名,则可以使用
.this. 的形式访问外部类中的成员。
-
匿名内部类:
-
new <类或接口>() { // 类的主体 };
-
匿名类和局部内部类一样,可以访问外部类的所有成员。如果匿名类位于一个方法中,则匿名类只能访问方法中 final 类型的局部变量和参数。(Java8新特性允许了)
-
匿名类中允许使用非静态代码块进行成员初始化操作。
-
匿名类的非静态代码块会在父类的构造方法之后被执行。
13. Java8新特性Effectively final
- 局部内部类和匿名内部类访问的局部变量不用必须由 final 修饰,所以这叫Effectively final功能
- 但是,规则没有改变,Lambda 表达式和匿名内部类访问的局部变量必须是 final 的,只是不需要程序员显式的声明变量为 final 的,从而节省时间。
14. Lambda 表达式
-
(参数列表) -> { // Lambda表达式体 } /** ->被称为箭头操作符或 Lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分: 左侧:Lambda 表达式的参数列表。 右侧:Lambda 表达式中所需执行的功能,用{ }包起来,即 Lambda 体。 */
-
必须是函数式接口才可以使用Lambda表达式(及一个接口中,有且只有一个抽象的方法(Object 类中的方法不包括在内))。
-
Java 8 提供了一个声明函数式接口注解 @FunctionalInterface
-
// 可计算接口 @FunctionalInterface public interface Calculable { // 计算两个int数值 int calculateInt(int a, int b); }
-
在接口之前使用 @FunctionalInterface 注解修饰,那么试图增加一个抽象方法时会发生编译错误。但可以添加默认方法和静态方法。
15. 输出方法
- printf 主要继承了C语言中 printf 的一些特性,可以进行格式化输出。
- print 就是一般的标准输出,但是不换行。
- println 和 print 基本没什么差别,就是最后会换行。
接下来看java基础学习(六)
内容总结
以上是互联网集市为您收集整理的java基础学习(五)全部内容,希望文章能够帮你解决java基础学习(五)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。