面向对象的基本思想
面向对象的基本概念
面向对象的基本概念指的是一种解决问题时考虑问题的思考方式,即通过对象来解决问题,这里的核心是寻找具备某种特定功能的类的对象。在java的世界里一切皆对象,所以在以后的学习过程中要将解决问题的思路进行转换。
面向对象和面向过程的关系
早期的编程思想是基于面向过程的,面向过程强调的是解决问题时,思考问题的每一个具体的细节,因而在实际的使用中,相对比较的繁琐。但是需要注意的是有了面向对象的编程思想后,面向过程的编程思想没有被取缔,主要是因为面向对象的内部其实也是基于面向过程的。因为如果具备一种特定功能的对象不存在的情况下,要想通过面向对象的思路解决问题,首相要做的第一件事请就是创建出这样的对象,那么在创建该对象,实现一种特定功能的过程,也是需要使用面向过程的思路来进行实现的。
类和对象
什么是类和对象
类是对一类事物的抽象的概念上的概括,而对象指的是某一类事物中实际存在的某一个个体。对自然界事物的描述无非就是通过对事物的概括来进行分类,然后再通过具体的个体的属性进行详细的区分。
类和对象的关系
类是一种抽象的概念上的意义,对象是一个实实在在存在的个体。类是无法直接使用的,要使用的话必须去实例化对象。类中定义了这一类事物所具有的属性和行为,类相当于一种模板,一个类可以有多个对象。
类的定义和对象的实例化
要定义一个类的话需要使用class关键字,其语法如下:
访问修饰符 class 类名称{
}
在类中通常包含属性和方法,分别对应自然界事物的特征和行为。在类中通常包含三部分:类中的属性,类中的方法,类中的构造方法。
public class Test {
public static void main(String[] args) {
//要使用类,那么必须首先进行类的对象的实例化操作,类名 对象名 = new 类名();
Person p = new Person();
//访问对象的属性:对象名.属性名称
p.name = "张三";
p.age = 20;
p.sex = '男';
p.phone = "13141502866";
//访问对象中属性的值
System.out.println("姓名:"+p.name+" 年龄:"+p.age+" 性别:"+p.sex+" 电话:"+p.phone);
//访问类中的方法
p.say();
p.eat("汉堡");
}
}
构造方法的使用
构造方法值得是在类中定义的方法名称与类名称相同,并且没有返回值声明的方法。那么既然构造方法没有返回值声明,那么在方法中也就不能使用return来返回运算的结果了。构造方法的一个重要的作用就是完成对类中属性的初始化的操作。
public class Person
{
// 定义类中的属性,相当于在类中去定义变量,但是要注意类中属性需要加上访问修饰符(public,默认)
String name;
int age;
char sex;
String phone;
private static String country;
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void setAge(int age)
{
if (age >= 0 && age <= 150)
{
this.age = age;
}
}
public int getAge()
{
return this.age;
}
public char getSex()
{
return sex;
}
public void setSex(char sex)
{
this.sex = sex;
}
public String getPhone()
{
return phone;
}
public void setPhone(String phone)
{
this.phone = phone;
}
// 无参的什么都不做的构造方法,构造方法通常用来完成对对象的属性的初始化操作
// 如果类中定义了构造方法,系统就不会去自动添加无参的构造方法。如果定义有参的构造方法必须同时提供一个无参的构造方法
public Person()
{
}
// 构造方法的重载
public Person(String name, int age, char sex, String phone)
{
// 访问变量的时候趋近原则,可以使用this来表示类中的属性
this.name = name;
this.setAge(age);
this.sex = sex;
this.phone = phone;
}
// 定义方法,相当于在类中去定义方法
public void say()
{
System.out.println("Hello");
}
public void eat(String food)
{
System.out.println("吃" + food);
}
public static String getCountry()
{
return country;
}
public static void setCountry(String country)
{
Person.country = country;
}
}
构造方法的定义
如果一个类中没有明确定义构造方法,那么代码在编译时会自动加上一个无参的什么都不做的构造方法,但是如果手动在类中定义了一个构造方法,那么程序在编译时就不会加上这样的构造方法了,所以,大家在以后的开发过程中需要注意,如果手动提供了有参的构造方法,一定要提供一个无参的构造方法。
构造方法的调用时机
构造方法是在实例化类的对象时进行调用的,那么在构造方法中通常用来完成对类中属性的初始化的操作。
匿名对象
匿名对象指的是没有具体声明的对象,那么这样的对象只能在实例化的开始进行使用,一旦使用完成以后,就不能继续使用了,会成为一块垃圾。
public class Test {
public static void main(String[] args) {
new Person().say();
}
}
字符串的使用
字符串是一种使用非常广泛的数据形式,主要掌握两种实例化方式和另种比较方式。
String的两种实例化方式和两种比较方式
通过new的范式进行实例化的操作,由于new表示开辟的堆内存,接下来回去判断常量池中是否存在该对象,如果不存在会创建该对象。使用new的方式至少会创建一个对象,也可能会创建两个对象。
使用直接赋值的形式,会判断常量池中是否已经存在该对象,如果不存在那么回去创建该对象。至多会创建一个对象,也可能一个都不创建。
public class StringDemo
{
public static void main(String[] args)
{
// 使用new实例化String对象
String str1 = new String("Hello");
String str2 = "Hello";
// 比较两个字符串的对象:使用==表示比较内存地址,
if (str1 == str2)
{
System.out.println("相同对象");
} else
{
System.out.println("不同对象");
}
// 使用equals方法来比较字符创的内容,从Object类中继承过来的,但是String重写了equals方法,似的该方法变成了比较内容的操作
if (str1.equals(str2))
{
System.out.println("内容相同");
} else
{
System.out.println("内容不同");
}
}
}
但是实际使用并没有这么简单,那么接下来我们开一下一下的问题。
String的内容一旦声明就不能改变
针对于String这样的特性,在开发中一定要注意不要经常修改String的内容,因为会创建很多其他的字字符串。
public class StringDemo {
public static void main(String[] args) {
String info = "a";
//循环修改info的内容
for(int i = 0 ; i < 100000 ; i++){
info = info + i;
}
System.out.println(info);
}
}
如果字符串的内容需要经常进行更改可以使用一个类:StringBuffer
public class StringDemo
{
public static void main(String[] args)
{
StringBuffer info = new StringBuffer("a");
// 循环修改info的内容
for (int i = 0; i < 100; i++)
{
info.append(i);
}
System.out.println(info);
}
}
String的常用方法
String的方法有很多,这里主要介绍一些常用的方法
import java.io.UnsupportedEncodingException;
public class StringDemo {
public static void main(String[] args) {
// 给定一个字符"abc中de国hsghja";
String str = "中abc";
// 表示将字符串转换成字节的形式
byte[] bs = str.getBytes();
// 调用有参的构造方法将字节数组转换成String对象
String info;
info = new String(bs,2,2);
System.out.println(info);
}
}
除此之外的其他的构造方法是用也是类似的,这里就不再一一介绍了
charAt()方法:
public class StringDemo {
public static void main(String[] args) {
String info = "Hello";
char c = info.toLowerCase().charAt(0);
System.out.println(c);
}
}
按照字典顺序进行比较:
public class StringDemo {
public static void main(String[] args) {
String info = "Hello";
int n = info.compareTo("Hello");
System.out.println(n);
}
}
当且仅当此字符串包含指定的 char 值序列时,返回 true:
public class StringDemo {
public static void main(String[] args) {
String info = "Hello";
boolean flag = info.contains("lll");
System.out.println(flag);
}
}
有很多的关于String的使用,大家可以查找Java api,学会以查找跟有效的阅读也是大家要学习的,这里就不多说了。
this关键字的使用
在java中this主要有一下几个作用:1、this可以用来表示类中的属性和方法;2、this可以用来表示当前对象;3、this可以表示调用构造方法。
使用this表示类中的属性或者方法
在构造方法以及setter方法中往往接收参数,那么为了将参数与类中的属性进行区分,这里可以使用this来表示类中的属性。
public class Person {
private String name;
private int age;
private char sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Person(){
}
public Person(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
以上的代码中的this就是用来表示类中的属性的作用。但是以上的作用和第二种作用相似。
this可以用来表示当前对象
使用this表示当前对象可以方便我们理解对统一各类的不同对象的操作
public class Test1 {
public static void main(String[] args) {
Person p1 = new Person("张三",20,'男');
Person p2 = new Person("李四",30,'男');
}
}
以上的代码完成的初始化的操作,就是跟据this来分别代表不同的对象来完成的。
使用this表示调用类中的构造方法
在类中往往也会进行构造方法的相互调用,这样可以降低代码的冗余。
public class Person {
private String name;
private int age;
private char sex;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Person(){
}
public Person(String name, int age, char sex) {
System.out.println("调用三个参数的构造方法");
this.name = name;
this.age = age;
this.sex = sex;
}
public Person(String name ,int age ,char sex , String phone){
//表示调用类中的构造方法,使用this表示调用构造方法只能放在代码的第一行
this(name,age,sex);
System.out.println("调用四个参数的够塑造方法");
this.phone = phone;
}
}
以上的代码可以发现使用this可以表示调用类中的构造方法,但是需要注意必须放在代码的第一行。初次之外还要注意避免出现方法的递归调用。
public class Person {
private String name;
private int age;
private char sex;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Person(){
//调用四个参数的构造方法来完成实例化操作
this("无名氏",1,'男',"110");
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
public Person(String name, int age, char sex) {
this(name,age);
this.sex = sex;
}
public Person(String name ,int age ,char sex , String phone){
//表示调用类中的构造方法,使用this表示调用构造方法只能放在代码的第一行
this(name,age,sex);
System.out.println("调用四个参数的够塑造方法");
this.phone = phone;
}
}
以上的代码不能出现反复的递归调用,如果出现那么程序将无法通过编译
static的使用
Static关键字的使用相对是比较容易的,就是该表示静态的意思,static在java中有两个作用:1、static表示静态可以修饰属性或者方法,如果属性和方法被static修饰,该属性或者方法将变成静态的属性和静态的方法。2、static还可以用来声明一个静态代码块。
使用static修饰的属性会成员全局属性,为该类的所有对象所共有。存在于全局数据区中。一旦某一个对象对该属性进行了修改,该类的所有其他对象的该属性也是相应进行修改。
使用static修饰方法,那么该方法将变成静态方法,静态方法可以使用类名进行直接的调用而不需要实例化类的对象。
public class Person {
private String name;
private int age;
private char sex;
private String phone;
private static String country;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Person(){
//调用四个参数的构造方法来完成实例化操作
this("无名氏",1,'男',"110");
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
public Person(String name, int age, char sex) {
this(name,age);
this.sex = sex;
}
public Person(String name ,int age ,char sex , String phone){
//表示调用类中的构造方法,使用this表示调用构造方法只能放在代码的第一行
this(name,age,sex);
System.out.println("调用四个参数的够塑造方法");
this.phone = phone;
}
public static String getCountry() {
return country;
}
public static void setCountry(String country) {
Person.country = country;
}
}
但是需要注意的是:非static的方法可以访问static的属性或者方法,但是static的方法只能访问static的属性活者方法。这也是main方法直接调用的方法必须使用static进行声明的原因。
理解main方法
在前面的内容中关于main,我们主要就是进行使用而没有进行相关的分析,那么在这里我们就对main方法的各个组成部分进行分析,包括main方法的初始化参数。
对于main方法执行所接受的参数,可以理解为当前程序要执行所需的初始化的参数。
public class Test2 {
public static void main(String[] args) {
if(!("zhoudazhong".equals(args[0])&&"1234".equals(args[1]))){
System.exit(0);
}
System.out.println("程序的相关运算");
}
}
代码块的使用
普通代码块就是使用大括号包裹起来的代码片段。普通代码块通常与变量的作用域关联。除此之外还有两种特殊的代码块:构造代码块、静态代码块
构造代码块
构造代码块指的是直接在类中定义的代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。
public class Student {
//定义构造代码块
{
System.out.println("调用构造代码块");
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(){
System.out.println("调用构造方法");
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
静态代码块
构造代码块指的是在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。如果类中包含多个静态代码块,那么将按照”先定义的代码先执行,后定义的代码后执行”。
public class Student {
//使用static定义的代码块叫做静态代码块
static{
System.out.println("调用静态代码块");
}
//定义构造代码块
{
System.out.println("调用构造代码块");
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(){
System.out.println("调用构造方法");
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
调用的代码:
public class Test3 {
static{
//加载一个类
try {
Class.forName("com.niit.zdz.objectdemo.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("调用主方法");
}
}
以上的代码可以看出静态代码块确实是在主方法之前当类被加载的时候调用。通常完成一些相关的资源和类库的加载工作。
对象数组
对象数组指的是包含一组相关对象的数组,而数组的使用必须先开辟空间,那么数组中存放的对象必须首先完成实例化的操作。
对象数组的动态初始化
对象数组的动态初始化是指首先定义一个指定长度的对象数组,然后在完成数组中对象元素的分别的实例化操作。
经过数组元素实例化以后的对象数组才能进行取值的操作,否则很可能会出现空指针异常。
public class Test4 {
public static void main(String[] args) {
Pet[] pets = new Pet[3];
//进行动态的元素的初始化
pets[0] = new Pet("Tom",20);
pets[1] = new Pet("Jerry",20);
pets[2] = new Pet("Kitty",10);
//遍历数组中的元素
for(Pet p : pets){
System.out.println("姓名:"+p.getName()+" 年龄:"+p.getAge());
}
}
}
但是要注意对象数组中的元素必须首先进行初始化以后才能进行使用,否则会出现空指针异常:java.lang.NullPointerException
public class Test4 {
public static void main(String[] args) {
Pet[] pets = new Pet[4];
//进行动态的元素的初始化
pets[0] = new Pet("Tom",20);
pets[1] = new Pet("Jerry",20);
pets[2] = new Pet("Kitty",10);
//遍历数组中的元素
for(Pet p : pets){
System.out.println("姓名:"+p.getName()+" 年龄:"+p.getAge());
}
}
}
由于对象数组的第四元素没有进行初始化的操作,所以不能去调用类中的方法。
对象数组的静态初始化
对象数组的静态初始化也基本数据类型的数组一致,指的是在为数组开辟内存空间的时候,就完成数组元素的初始化操作,只是在这里初始化的不是基本数据类型的值,而是类的对象。
public class Test4 {
public static void main(String[] args) {
Pet[] pets = {new Pet("Tom",20),new Pet("Jerry",20),new Pet("Kitty",10)};
//遍历数组中的元素
for(Pet p : pets){
System.out.println("姓名:"+p.getName()+" 年龄:"+p.getAge());
}
}
}
引用传递的进一步理解
引用传递与对象的引用传递时一样的,都是表示在进行赋值操作的时候,传递的是在栈内存中保存的堆内存地址。
class Demo {
int num = 30;
}
public class Test5{
public static void main(String[] args) {
Demo d = new Demo();
d.num = 50;
System.out.println("调用方法前num的值"+d.num);
fun(d);
System.out.println("调用方法后num的值"+d.num);
}
public static void fun(Demo demo){
demo.num = 1000;
}
}
public class Test6 {
public static void main(String[] args) {
String str1 = "Hello";
System.out.println("调用方法前str1的值:"+str1);
fun(str1);
System.out.println("调用方法后str1的值:"+str1);
}
public static void fun(String s){
s = "NIIT";
}
}
class Demo {
String str = "Hello";
}
public class Test5{
public static void main(String[] args) {
Demo d = new Demo();
d.str = "World";
System.out.println("调用方法前num的值"+d.str);
fun(d);
System.out.println("调用方法后num的值"+d.str);
}
public static void fun(Demo demo){
demo.str = "NIIT";
}
}
面向对象的继承特征
面向对象的继承一方面指的是子类对父类的属性或者方法的继承,同时更重要的是对父类中的属性和方法进行扩展。
继承的基本实现
要实现继承首先需要定义父类,还要使用extends关键字去定义该父类的子类;其语法如下:
Class 子类 extends 父类{
}
继承的实际意义在哪里?
父类:
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("Hello");
}
public void eat(){
System.out.println("吃饭");
}
}
子类:
public class Student extends Person{
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public void study(){
System.out.println("学习");
}
}
测试类:
public class Test1 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("张三");
stu.setAge(30);
stu.setSchool("北大清华");
//调用对象的方法
stu.say();
stu.eat();
stu.study();
}
}
结果:
java中继承的限制
在java中对于继承的支持是只支持:单继承,即一个子类只能继承一个父类,并不支持多继承。但是java中是可以支持多重继承。
在使用继承的时候,子类不能访问父类中的私有成员变量,但是可以调用父类中公有的方法。
public class Student extends Person{
private String school;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
//对于父类中的私有的属性子类能不能继承的问题
public void study(){
System.out.println(this.getName()+"学习");
}
}
以上的代码可看出子类却是不能直接访问父类中的私有的属性,但是可以通过共有的方法来访问父类中的私有的属性。
子类对象的实例化过程
对子类对象的实例化的操作需要去调用子类中定义的构造方法,那么子类的实例化与父类有什么关系呢?
实际上子类对象在调用构造方法之前首先调用了父类中的构造方法,实例化出了父类对象啊,然后再调用子类的构造方法。
public class Person {
public String name;
public int age;
public Person(){
System.out.println("调用父类的构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("Hello");
}
public void eat(){
System.out.println("吃饭");
}
}
public class Student extends Person{
private String school;
public Student(){
System.out.println("调用子类的构造方法");
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
//对于父类中的私有的属性子类能不能继承的问题
public void study(){
System.out.println(this.getName()+"学习");
}
}
以上的代码应该首先调用的子类的构造方法,那么为什么会首先去执行父类的构造方法呢?主要原因在于,当编译子类的构造方法时,系统会自动在构造方法的第一行加上一行语句:super();
方法的覆写
在继承关系中也存在着方法覆写的概念,所谓的方法覆写指的是在子类中定义与父类中方法名称、返回值类型和参数列表完全一致,以实现子类所特定需求的功能。但是需要注意的是,被子类覆写的方法不能拥有比父类中方法更加严格的访问权限,否则会出现错误。
public class Person {
public String name;
public int age;
public Person(){
System.out.println("调用父类的构造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void say(){
System.out.println("Hello");
}
public void eat(){
System.out.println("吃饭");
}
public void tell(){
System.out.println("姓名:"+this.name +" 年龄:"+this.age);
}
}
public class Student extends Person{
private String school;
public Student(){
//表示默认调用父类中的无参的构造方法,super()只能放在代码的第一行。
super();
System.out.println("调用子类的构造方法");
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
//对于父类中的私有的属性子类能不能继承的问题
public void study(){
System.out.println(this.getName()+"学习");
}
//这样发现从父类中继承过来的方法不能够满足子类的需要时,子类需要覆写父类中的方法
//java中的注解:强制告诉编译器,一下的方法是覆写父类中的方法
//方法的覆写指的是在子类中定义域父类中方法名称、返回值类型,参数列表完全一致的方法;访问权限不能比父类中的方法更加严格
@Override
public void tell() {
//super的作用与this类似,表示调用父类中的方法
System.out.println("姓名:"+this.name+" 年龄:"+this.age+" 学校:"+this.school);
}
}
方法的重载和覆写
this和super的使用和区别
继承的实际应用
继承在实际的使用中。主要是通过分类来定义相同的属性和共同的方法。子类就可以通过继承父类来天然的获取这些属性和方法,从而提高代码的复用性。
父类:
public class IntArray {
private int[] nums;
public int[] getNums() {
return nums;
}
public void setNums(int[] nums) {
this.nums = nums;
}
int foot;
public IntArray(int len){
nums = new int[len];
}
public boolean add(int num){
if(foot<nums.length){
nums[foot] = num;
foot++;
return true;
}
return false;
}
public void print(){
for(int n : this.nums){
System.out.print(n+" ");
}
}
}
排序类:
import java.util.Arrays;
public class SortArray extends IntArray{
public SortArray(int len) {
super(len);
}
//实现排序的输出
@Override
public void print() {
//对数组进行排序
Arrays.sort(this.getNums());
//遍历
super.print();
}
}
反转类:
public class ReverseArray extends IntArray {
public ReverseArray(int len) {
super(len);
}
@Override
public void print() {
//实现对数组元素倒序
reverse();
//输出数组元素
super.print();
}
public void reverse(){
int[] arr = this.getNums();
//循环进行交换操作
for(int i = 0 ; i < arr.length/2 ; i++){
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
}
测试类:
public class Test1
{
public static void main(String[] args)
{
SortArray sa = new SortArray(6);
// 箱数组中添加数据
System.out.println(sa.add(5));
System.out.println(sa.add(8));
System.out.println(sa.add(7));
System.out.println(sa.add(11));
System.out.println(sa.add(3));
System.out.println(sa.add(6));
sa.print();
ReverseArray ra = new ReverseArray(6);
// 箱数组中添加数据
System.out.println(ra.add(5));
System.out.println(ra.add(8));
System.out.println(ra.add(7));
System.out.println(ra.add(11));
System.out.println(ra.add(3));
System.out.println(ra.add(6));
// 遍历
ra.print();
}
}
final关键字的使用
final可以修饰类中的属性方法以及类都可以,final修饰属性,那么该属性将变成终极属性,变成类中的常量,一旦声明内容就不能改变;final修饰方法,该方法将变成终极方法,这种方法不能被子类覆写;final还可以修饰类,一旦修饰了类该类将变成最终类,最终类不能有子类。
final public class Person {
public final String name = "zhangsan";
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
final public void say(){
System.out.println("Hello");
}
}
final的使用是相对简单,通常的开发中的使用注意的是定义常量。