面向对象概述 面向对象三大特征:
封装(Encapsulation)
继承(Inheritance)
多态(Polymorphism)
类和类成员: 属性、方法、构造器(前三个重要);代码块、内部类
其他关键字: this, super, static, final, abstract, interface, package, import
属性(成员变量)和局部变量:
* 同: * 定义格式:数据类型 变量名 = 变量值 * 先声明后使用 * 都有其作用域 * * 异: * 1. 声明位置不同 * 属性:直接定义在{}内 * 局部变量:声明在方法内部、方法形参、代码块内、构造器形参、构造器内部的变量 * 2. 关于权限修饰符的不同 * 属性:可以在声明属性时候使用权限修饰符 * 如:public private , 缺省, protected * 局部变量:不能用权限修饰符 * 3. 默认初始化值 * 属性:类的属性,根据其类型有初始化默认值 * 局部变量:没有默认初始化值(意味着,我们在调用局部变量的时候一定要显式赋值) * 特别的,形参在调用时赋值即可 * 4. 二者在内存中加载的位置 * 属性:加载到堆空间(非static ) * 局部变量:加载到栈空间
方法:
* 定义格式: * 权限修饰符 返回值类型 方法名(形参列表){ * 方法体 * } * 注意:static 、final 、abstract 来修饰的方法,后面再讲 * * 1. 四种权限修饰符:public 、private 、缺省、 protected * 2. 返回值类型; * 有返回值 vs 无返回值(void ,通常不需要return ,非要写的话就return ;) * return 之后不可以跟语句了
类的基本结构:
package cn.xpshuai.test;public class PersonTest { public static void main (String[] args) { } } class Person { String name; int age; boolean isMarried; public Person () {} public Person (String n, boolean im) { name = n; isMarried = im; } public void walk () { System.out.println("人走路..." ); } public String display () { return "名字:" + name + "婚否:" + isMarried; } { name = "韩梅梅" ; age = 17 ; isMarried = true ; } class pet { String name; float weight; } }
小练习:
package cn.xpshuai.test;public class StudentsTest { public static void main (String[] args) { Students[] stus = new Students[20 ]; for (int i = 0 ; i < stus.length; i++) { stus[i] = new Students(); stus[i].num = i + 1 ; stus[i].state = (int )(Math.random() * (6 -1 +1 )+1 ); stus[i].score = (int )(Math.random() * (100 -0 +1 )); } StudentsTest testStu = new StudentsTest(); testStu.searchState(stus, 3 ); testStu.BubbleSort(stus); System.out.println("----------------排序完成---------------" ); testStu.printStutent(stus); } public void printStutent (Students[] stus) { for (int i = 0 ; i < stus.length; i++) { System.out.println(stus[i].info()); } } public void searchState (Students[] stus, int sta) { for (int i = 0 ; i < stus.length; i++) { if (stus[i].state == sta) { System.out.println(sta + "年级学生:" + stus[i].info()); } } } public void BubbleSort (Students[] stu) { for (int i = 0 ; i < stu.length-1 ; i++) { for (int j = 0 ; j < stu.length-1 -i; j++) { if (stu[j].score > stu[j+1 ].score) { Students temp = stu[j]; stu[j] = stu[j+1 ]; stu[j+1 ] = temp; } } } } } class Students { int num; int state; int score; public String info () { return "学号:" + num + ",年级" + state + ",成绩:" + score; } }
匿名对象 package cn.xpshuai.testc;public class InstanceTest { public static void main (String[] args) { Phone p1 = new Phone(); System.out.println(p1); p1.sendEmail(); new Phone().sendEmail(); new Phone().price = 1999 ; new Phone().showPrice(); PhoneMall mall = new PhoneMall(); mall.show(new Phone()); } } class Phone { double price; public void sendEmail () { System.out.println("发邮件" ); } public void playGame () { System.out.println("打游戏" ); } public void showPrice () { System.out.println("价格为:" + price); } } class PhoneMall { public void show (Phone p) { p.sendEmail(); p.playGame(); } }
方法的重载(overload)
区分与后面的重写
重载: 在同一个类中,允许存在—个以上的同名方法 ,只要它们的参数个数或参数类型不同 即可。
特点: 与返回值类型无关,只看参数列表 ,且参数列表必须不同(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
如下两个同名方法构成了重载:
public class { public void reverseArr (int [] arr) { for (int i = 0 ; i < arr.length; i++) { int tmp = arr[i]; arr[i] = arr[arr.length-i-1 ]; arr[arr.length-i-1 ] = tmp; } } public void reverseArr (String[] arr) { for (int i = 0 ; i < arr.length; i++) { String tmp = arr[i]; arr[i] = arr[arr.length-i-1 ]; arr[arr.length-i-1 ] = tmp; } } }
可变个数的形参(新特性)
jdk5.0新增的内容
格式:func(数据类型 ... 参数名)
当调用可变个数形参方法时,传入参数**个数可为 0到多个**
可变个数形参的方法与本类中方法名相同,形参不同的方法之间**构成重载**
可变个数形参在方法的形参中,必须声明在**末尾**(形参列表的最后一个位置)
可变个数形参在方法的形参中,最多只能声明一个 可变形参。
public class ArgumentsTest { public static void main (String[] args) { ArgumentsTest a = new ArgumentsTest(); a.show(11 ); a.show("hello" ); a.show("hello" , "world" ); a.show(new String[] {"AAA" , "BBB" , "CCC" }); } public void show (int i) { } public void show (String s) { } public void show (String ... strs) { for (int i = 0 ; i < strs.length; i++) { System.out.println(strs[i]); } } }
方法参数的值传递机制 关于变量的赋值:
如果变量是基本数据类型:此时赋值的是变量所保存的数据值
如果变量是引用数据类型:此时赋值的是变量所指向的地址
方法形参的传递机制: 【值传递机制】
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
public class ValueTranslation { public static void main (String[] args) { System.out.println("*********基本数据类型**********" ); int m = 10 ; int n = m; System.out.println(m + "\t" + n); n = 20 ; System.out.println(m + "\t" + n); System.out.println("*********引用数据类型**********" ); Order o1 = new Order(); o1.id =1001 ; Order o2 = o1; System.out.println(o1.id + "\t" + o2.id); o2.id =1002 ; System.out.println(o1.id + "\t" + o2.id); System.out.println("*********方法形参的值传递**********" ); int i = 10 ; int j = 20 ; System.out.println(i + "\t" + j); ValueTranslation test = new ValueTranslation(); test.swap1(i, j); System.out.println(i + "\t" + j); System.out.println("*********方法形参的引用数据类型传递**********" ); Data data = new Data(); data.x = 10 ; data.y = 20 ; System.out.println(data.x + "\t" + data.y); ValueTranslation test2 = new ValueTranslation(); test2.swap2(data); System.out.println(data.x + "\t" + data.y); } public void swap1 (int i, int j) { int tmp = i; i = j; j = tmp; } public void swap2 (Data data) { int tmp = data.x; data.x = data.y; data.y = tmp; } } class Order { int id; } class Data { int x; int y; }
但是,String作为引用数据类型,是例外的,是不能交换成功的,因为它存在字符串常量池中,会新造一个地址。所以,记下面这个结论:
如果变量是基本数据类型:此时赋值的是变量所保存的数据值
如果变量是引用数据类型:此时赋值的是变量所指向的地址
自定义封装Arrayutil类:
package cn.xpshuai.testc;public class ArayUtil { public int getMax (int [] arr) { int max = 0 ; for (int i = 0 ; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } public int getMin (int [] arr) { int min = 0 ; for (int i = 0 ; i < arr.length; i++) { if (arr[i] < min) { min = arr[i]; } } return min; } public int getSum (int [] arr) { int sum = 0 ; for (int i = 0 ; i < arr.length; i++) { sum += arr[i]; } return sum; } public int getMiddle (int [] arr) { return getSum(arr) / arr.length; } public void reverseArr (int [] arr) { for (int i = 0 ; i < arr.length; i++) { int tmp = arr[i]; arr[i] = arr[arr.length-i-1 ]; arr[arr.length-i-1 ] = tmp; } } public void reverseArr (String[] arr) { for (int i = 0 ; i < arr.length; i++) { String tmp = arr[i]; arr[i] = arr[arr.length-i-1 ]; arr[arr.length-i-1 ] = tmp; } } public int [] copyArr(int [] arr) { int [] arr2 = new int [arr.length]; for (int i = 0 ; i < arr2.length; i++) { arr2[i] = arr[i]; } return arr2; } public void printArr (int [] arr) { System.out.print("{" ); for (int i = 0 ; i < arr.length; i++) { System.out.print(arr[i] + ", " ); } System.out.print("}" ); } public void sortArr (int [] arr) { for (int i = 0 ; i < arr.length-1 ; i++) { for (int j = 0 ; j < arr.length-1 -i; j++) { if (arr[j] > arr[j+1 ]) { swap(arr, j, j+1 ); } } } } public void swap (int [] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } public int getIndex (int [] arr, int dest) { for (int i = 0 ; i < arr.length; i++) { if (arr[i] == dest) { return 1 ; } } return -1 ; } }
画内存图
1.内存结构:
栈(局部变量)
堆(new出来的结构:对象、数组)
2.变量:成员变量&局部变量(方法内、方法形参、构造器内、构造器形参、代码块内)
封装性 隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来 。这就是封装性的设计思想。
封装性与隐藏:
在对对象发属性进行赋值时,赋值操作要受到数据类型和存储范围的制约。除此之外没有其他制约条件。但是,在实际问题中,我们往往需要给属性赋值 *加入额外的限制条件,这个条件就不能再属性声明时候体现,我们只能通过方法进行限制条件的添加。 * 同时我们需要避免用户再使用"对象.属性" 方式进行赋值,则需要将属性声明为private * -->此时针对属性,就体现了封装性
封装性体现:
1. 我们将类的属性私有化(private ),同时,提供公共的(public )方法来获取(getXXX)和设置(setXXX)此属性的值2. 不对外暴露私有方法3. 单例模式4. ... ...
权限修饰符:
* 封装性的体现需要权限修饰符来配合: * 1. java规定的四种权限(从小到大排序):private 、缺省(即default ,不用写的时候)、protected 、public * 详细见笔记 * 2. 四种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类 * 3. 具体的,四种权限都可以用来修饰内部结构:属性、方法、构造器、内部类 * 修饰类的话:只能用public 和 缺省
封装性总结:
Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
public class AnimalTest { public static void main (String[] args) { Animal a = new Animal(); a.setName("大黄" ); a.setAge(2 ); a.setLegs(6 ); a.show(); OrderTest o1 = new OrderTest(); o1.b = 111 ; o1.c = 222 ; o1.test2(); o1.test3(); } } class Animal { private String name; private int age; private int legs; public void setLegs (int l) { if (l >= 0 && l % 2 == 0 ) { legs = l; }else { legs = 0 ; } } public int getLegs () { return legs; } public void setAge (int a) { if (a >= 0 ) { age = a; }else { age = 0 ; } } public int getAge () { return age; } public void setName (String n) { name = n; } public String getName () { return name; } public void eat () { System.out.println("动物进食" ); } public void show () { System.out.println("动物的名字" + name + ",年龄:" + age + ",腿个数:" + legs); } }
权限测试例子:
public class OrderTest2 { public static void main (String[] args) { OrderTest o1 = new OrderTest(); o1.c = 222 ; o1.test3(); } }
构造器 特征:
它具有与类相同的名称
它不声明返回值类型(与声明为void不同)
不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
作用: 创建对象,初始化对象的属性
注意:
如果没有显式的定义类构造器的话,则系统默认 提供一个空参 的构造器
定义构造器的格式:权限修饰符 类名(形参列表){}
构造器 不是方法
一个类中定义多个构造器构成重载
一旦显式的定义类的构造器,系统就不再提供默认的空参构造器
一个类中,至少 会有一个 构造器
如下:
public class PeopleTest { public static void main (String[] args) { People p = new People("Tom" , 18 ); p.walk(); } } class People { String name; int age; public People () { System.out.println("构造器1被调用..." ); } public People (String n) { System.out.println("构造器1被调用..." ); name = n; } public People (String n, int a) { System.out.println("构造器1被调用..." ); name = n; age = a; } public void walk () { System.out.println("人走路..." ); } }
总结-属性赋值过程(按优先顺序):
默认初始化
显式初始化
构造器中初始化
通过对象.属性
或对象.方法
的方式赋值
JavaBean JavaBean:是一种Java语言写成的可重用组件。
所谓javaBean,是指符合如下标准的Java类:
类是公共(public)的
有一个无参的公共的构造器
有属性,且有对应的getXXX、setXXX方法
满足这样三个条件的一个类,就叫JavaBean
也可以通过反射来造对象
UML类图
this关键字
this表示当前对象,可以调用类的属性、方法和构造器
它在方法内部使用,即这个方法所属对象的引用
它在构造器内部使用,表示该构造器正在初始化的对象
package cn.xpshuai.www;public class ThisTEst { public static void main (String[] args) { People2 p1 = new People2("Tom" , 12 ); System.out.println(p1.getAge()); } } class People2 { String name; int age; public People2 () { System.out.println("构造器1被调用..." ); this .eat(); } public People2 (String name) { this (); System.out.println("构造器2被调用..." ); this .name = name; } public People2 (String name, int age) { this (name); this .age = age; System.out.println("构造器3被调用..." ); } public void setName (String name) { this .name = name; } public String getName () { return this .name; } public void setAge (int age) { this .age = age; } public int getAge () { return this .age; } public void walk () { System.out.println("人走路..." ); } }
Eclipse快速生成get和set等方法:alt + seift +s
快捷键就可以看到啦
Eclipse快速生成get和set等方法:alt +insert
快捷键就可以看到啦
package * package 关键字的使用: * 1. 为了实现更好项目中类的管理,提出了“包”的概念 * 2. 使用package 声明类或者接口所属的包,声明在源文件的首行 * 3. 包,属于标识符,遵循标识符命名规范(小写)、见名知意 * 4. 每"." 一次,就代表一层文件目录 * * 补充:同一个包下,不能命名同名的接口、类, 不同包下可以命名同名的接口、类
继承性
Java只支持单继承和多层继承 ,不允许多重继承
Object类是所有类的根父类
简单例子如下:
测试类:
package cn.xpshuai.java;public class ExtendsTest { public static void main (String[] args) { Person p1 = new Person("张三" , 18 ); p1.eat(); Student s1 = new Student("GIS" ); s1.setName("张三三" ); s1.setAge(22 ); s1.show(); } }
父类:
package cn.xpshuai.java;public class Person { private String name; private int age; public Person () { } public Person (String name, int age) { this .name = name; this .age = 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 eat () { System.out.println("吃" ); } public void sleep () { System.out.println("睡觉" ); } }
子类:
public class Student extends Person { private String major; public Student () { super (); } public Student (String major) { super (); this .major = major; } public String getMajor () { return major; } public void setMajor (String major) { this .major = major; } public void study () { System.out.println("学习" ); } public void show () { System.out.println("姓名:" + getName() + ", 年龄:" + getAge() + ",专业:" + getMajor()); } @Override public void eat () { System.out.println("学生应该多吃" ); } }
方法的重写(override 、 overwrite)
与前面的”重载”区分
定义: 在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖 。在程序执行时,子类的方法将覆盖父类的方法(子类根据需要对从父类继承来的方法进行改造)。
要求:
子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表
子类重写的方法的返回值类型不能大于 父类被重写的方法的返回值类型
子类重写的方法使用的访问权限不能小于 父类被重写的方法的访问权限
子类方法抛出的异常不能大于父类被重写方法的异常
注意:
子类与父类中同名同参数的方法必须同时声明为非static的 (即为重写)
若同时声明为static的〈不叫重写),因为static方法是属于类的,子类无法覆盖父类的方法。
* 【重写】override 、 overwrite * 子类根据需要对从父类继承来的方法进行改造 * * 形式:权限修饰符 (可选:static /final ) 返回值类型 方法名(形参列表) throws 异常的类型{ * * } * * 1. 必须与父类被重写的方法具有“相同的方法名称、参数列表” * 2. 子类重写的方法的返回值类型“不能大于”父类被重写的方法的返回值 * >父类被重写的方法的返回值类型是void ,则子类重写的方法的返回值类型只能是void * >父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类 * >父类被重写的方法的返回值类型是基:本据类型,则子类重写的方法的返回值类型必须是相同的基本数据类型 * 3. 子类重写的方法使用的当问权限“不能小于”父类被重写的方法的访问权限 * >子类不能重写父类中private 的方法 * 4. 子类方法抛出的异常不能大于父类被重写方法的异常 * > * * 子类与父类中同名同参数的方法必须同时声明为非static 的(即为重写),或者同时声明为static 的(不是重写)。因为static 方法是属于类的,子类无法覆盖父类的方法。 *
super关键字
子类重写了父类的方法之后,可以用super调用父类中的方法
super可以调用:属性、方法、构造器
super调用属性和方法:
我们可以在子类的方法或构造器中。通过使用super.属性
或super.方法
的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略super.
特殊情况: 当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用super.属性
的方式,表明调用的是父类中声明的属性。
特殊情况: 当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用super.方法
的方式,表明调用的是父类中被重写的方法。
super调用父类构造器: *
我们可以在子类的构造器中显式的使用super(形参列表)
的方式,调用父类中声明的指定的构造器
super(形参列表)
的使用,必须声明在子类构造器的首行!
我们在类的构造器中,针对于this(形参列表)
或super(形参列表)
只能二选一 ,不能同时出现
在构造器的首行,没有显式的声明this(形参列表)
或super(形参列表)
,则默认调用的是父类中空参的构造方法
在类的多个构造器中,至少有一个类的构造器中使用了super(形参列表)
,调用父类中的构造器
子类对象实例化的全过程:
1 .从结果上来看:(继承性) * 子类继承父类以后,就获取了父类中声明的属性或方法。 * 创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。 2 .从过程上来看; * 当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,直到调用了java.lang.0bject类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。 * 明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new 的子类对象。
如子类:
public class Student extends Person { private String major; private int id = 1002 ; public Student () { super (); } public Student (String name, int age, String major) { super (name, age); this .major = major; } public int getId () { return id; } public void setId (int id) { this .id = id; } public Student (String major) { super (); this .major = major; } public String getMajor () { return major; } public void setMajor (String major) { this .major = major; } public void study () { System.out.println("学习" ); } @Override public void eat () { System.out.println("学生应该多吃有营养的食物..." ); super .sleep(); } public void show () { System.out.println("姓名:" + getName() + ", 年龄:" + getAge() + ",专业:" + getMajor()); System.out.println(this .getId()); System.out.println(super .getId()); } }
测试类:
public class ExtendsTest { public static void main (String[] args) { Person p1 = new Person("张三" , 18 ); p1.eat(); Student s1 = new Student("GIS" ); s1.setName("张三三" ); s1.setAge(22 ); s1.show(); s1.eat(); Student s2 = new Student("小李" , 18 , "CS" ); s2.show(); } }
多态性(Polymorphism) 对象的多态性: 父类的引用指向子类的对象(可以直接应用在抽象类和接口上)
Java引用变量有两个类型:
编译时类型:由声明该变量时候使用的类型决定
运行时类型:由实际赋给该变量的对象决定
简称:编译看左,运行看右
虚拟方法
问:多态是编译时行为还是运行时行为?
答:运行时行为
instanceof操作符 x instanceof A
:检验x是否为类A的对象,返回值为boolean类型
要求x所属的类与类A必须是子类和父类的关系,否则编译错误
如果x属于类A的子类B(间接父类子类关系),也可以使用
instanceof情景:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof判断
toString() 输出样式,可以手动重写子类中的该方法
finalize() 对象回收之前会调用这个方法:finalize(), 子类可重写
class B { @Override protecred void finalize () throws Throwable { System.out.println("对象被释放--> " = this ); } ... } System.gc();
== 与 equals()
import java.sql.Date;public class EqualsTest { public static void main (String[] args) { int i = 10 ; char c = 10 ; System.out.println( c == i); char c1 = 'A' ; char c2 = 65 ; System.out.println(c1 == c2); Customer customer1 = new Customer("xxx" ); Customer customer2 = new Customer("xxx" ); System.out.println(customer1 == customer2); String s1 = new String("asd" ); String s2 = new String("asd" ); System.out.println(s1 == s2); System.out.println(s1.equals(s2)); System.out.println(customer1.equals(customer2)); Date date1 = new Date(2354534654L ); Date date2 = new Date(2354534654L ); System.out.println(date1.equals(date2)); } } class Customer { String name; 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 Customer () { } public Customer (String name) { this .name = name; } public Customer (String name, int age) { this .name = name; this .age = age; } @Override public boolean equals (Object obj) { if (this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; Customer other = (Customer) obj; if (age != other.age) return false ; if (name == null ) { if (other.name != null ) return false ; } else if (!name.equals(other.name)) return false ; return true ; } }
重写equals()方法的原则:
包装类 单元测试 步骤如下:
package cn.xpshuai.java3;import org.junit.Test;public class JUnitTest { int num = 10 ; @Test public void testEquals () { String s1 = new String("y" ); String s2 = new String("yyy" ); System.out.println(s1 == s2); System.out.println(s1.equals(s2)); System.out.println(num); } @Test public void testToString () { System.out.println(num); } }
包装类(Wrapper)的使用
让基本数据类型也具有类的特征,封装起来
基本类型、包装类、String三种类型相互转换:
package cn.xpshuai.java3;import org.junit.Test;public class WrapperTest { public static void main (String[] args) { } @Test public void test1 () { int num1 = 10 ; Integer in1 = new Integer(num1); System.out.println(in1.toString()); Integer in2 = new Integer("132" ); System.out.println(in2.toString()); Float float1 = new Float("11.1" ); System.out.println(float1); Boolean boolean1 = new Boolean("tRuE" ); Boolean boolean2 = new Boolean("true123" ); System.out.println(boolean1); System.out.println(boolean2); System.out.println(boolean2); Order order = new Order(); System.out.println(order.isMan); System.out.println(order.isFemale); } @Test public void test2 () { Integer in1 = new Integer(12 ); int i1 = in1.intValue(); System.out.println(i1 + 11 ); } @Test public void test3 () { int num1 = 10 ; int num2 = 11 ; Integer in2 = num2; boolean isFlag = true ; Boolean isFlag2 = isFlag; int num3 = in2; } public void method1 (Object obj) { System.out.println(obj); } @Test public void test4 () { int num1 = 10 ; String str1= num1 + "" ; float f2 = 12.3f ; String string = String.valueOf(f2); System.out.println(string); Double d1 = new Double(12.5 ); String string2 = String.valueOf(d1); System.out.println(string2); } @Test public void test5 () { String str1 = "123" ; int num2 = Integer.parseInt(str1); System.out.println(num2); } } class Order { Boolean isMan; boolean isFemale; }
Vector()可以代替数组,后续再说…
关键字:static 无论产生了多少个对象,只希望某些特定的数据在内存空间中只有一份
static可以用来修饰:属性、方法、代码块、内部类
static修饰属性: 静态变量
属性按照是够使用static 修饰分为:静态属性 vs 非静态属性(实例变量) 实例变量:创建的多个对象,每个对象都独立拥有一套类中的非静态属性。当修改其中一个非静态属性时不会影响另一个对象中相同属性值的修改 静态属性:创建了类的多个对象,公用同一个静态变量,当通过某一个对象修改该静态变量时,会导致其他对象调用该静态变量时是修改过的 * * (1 )静态变量随着类的加载而加载: "类.静态变量" 方式进行调用 * (2 )静态变量的加载要早于对象的创建 * (3 )由于类只会记载一次,则静态变量在内存中也会只存在一份:存在方法区的静态域 * 举例:System.out Math.PI
static修饰方法:
静态方法随着类的加载而加载: "类.静态方法" 方式进行调用 静态方法中,只能调用静态的方法或属性 非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性 在静态的方法内,不能使用this 关键字、super 关键字 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。
public class StaticClass { public static void main (String[] args) { Chinese.nation = "CHN" ; Chinese c1 = new Chinese(); c1.name = "姚明" ; c1.age = 40 ; Chinese c2 = new Chinese(); c2.name = "马龙" ; c2.age = 30 ; System.out.println(c2.nation); Chinese.show(); } } class Chinese { String name; int age; static String nation; public static void show () { System.out.println("我是一个中国人!!!" ); Chinese.nation ="CHN" ; } public void show2 () { System.out.println("我是一个中国人2!!!" ); Chinese.nation ="CHN" ; System.out.println(this .name); } }
类变量和实例变量内存解析
单例模式 package cn.xpshuai.java4;public class SingleTonTest { public static void main (String[] args) { Bank bank1 = Bank.getIntance(); Bank bank2 = Bank.getIntance(); System.out.println(bank1 == bank2); Order order1 = Order.getInstance(); Order order2 = Order.getInstance(); System.out.println(order1 == order2); } } class Bank { private Bank () { } private static Bank instance1 = new Bank(); public static Bank getIntance () { return instance1; } } class Order { private Order () { } private static Order instance2 = null ; public static Order getInstance () { if (instance2 == null ) { instance2 = new Order(); } return instance2; } }
一个.java源文件只能有一个public的类
代码块 package cn.xpshuai.java4;public class BlockTest { public static void main (String[] args) { String desc = Person.desc; Person p1 = new Person(); System.out.println(desc); } } class Person { String name; int age; static String desc = "我是一个人" ; public Person () { } public Person (String name, int age) { super (); this .name = name; this .age = age; } { System.out.println("hello非静态代码块1" ); age = 1 ; eat(); info(); desc = "hhhhhh" ; } { System.out.println("hello非静态代码块2" ); age = 1 ; } static { System.out.println("hello静态代码块1" ); info(); desc = "重新赋值,我是一个爱学习的人1" ; } static { System.out.println("hello静态代码块1" ); desc = "重新赋值,我是一个爱学习的人2" ; } public void eat () { System.out.println("人吃饭" ); } @Override public String toString () { return "Person [name=" + name + ", age=" + age + "]" ; } public static void info () { System.out.println("我是一个快乐的人" ); } }
final 关键字 final可以修饰的结构:类、方法、变量
package cn.xpshuai.java4;public class FinalTest { public static void main (String[] args) { AA aa = new AA(); aa.setDown(10 ); } } final class FinalA { } class AA { final String NAME = "aaa" ; final int WIDTH; final int HEIGHT; { WIDTH =10 ; } public AA () { HEIGHT = 10 ; } public AA (int n) { HEIGHT = n; } public final void show () { } public void setDown () { final int NUM = 11 ; } public void setDown (final int num) { System.out.println(num); } }
抽象类与抽象方法(重要)
abstract
有时将一个父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类。
package cn.xpshuai.java5;public class AbstractTest { public static void main (String[] args) { } } abstract class Person { private String name; private int age; public Person () { } public Person (String name, int age) { this .name = name; this .age = 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 eat () { System.out.println("人:吃饭" ); } public void walk () { System.out.println("人:走路" ); } abstract public void play () ; } class Student extends Person { public Student (String name, int age) { super (name, age); } @Override public void play () { System.out.println("学生玩" ); } }
创建抽象类的匿名子类对象
package cn.xpshuai.java5;public class PersonTest { public static void main (String[] args) { method(new Student("tom" , 19 )); Worker worker = new Worker(); method1(worker); method1(new Worker()); Person p = new Person() { @Override public void play () { System.out.println("匿名重写" ); } }; method1(p); method1(new Person() { @Override public void play () { System.out.println("玩好玩的东西" ); } }); } public static void method (Student s) { } public static void method1 (Person p) { } } class Worker extends Person { @Override public void play () { System.out.println("工人娱乐" ); } }
多态的应用: 模板方法设计模式
接口(Interface)(重要) package cn.xpshuai.java5;public class InterfaceTest { public static void main (String[] args) { Plane plane = new Plane(); plane.fly(); } } interface AttackAble { void attack () ; } interface Flyable { public static final int MAX_SPEED = 7900 ; int MIN_SPEED = 1 ; public abstract void fly () ; void stop () ; } class Plane implements Flyable { @Override public void fly () { System.out.println("飞机通过引擎起飞" ); }; @Override public void stop () { System.out.println("驾驶员减速停止" ); }; } abstract class Kite implements Flyable { @Override public void fly () { System.out.println("风筝通过风起飞" ); }; } class Bullet extends Object implements Flyable , AttackAble { @Override public void attack () { } @Override public void fly () { } @Override public void stop () { } } interface AA { void method1 () ; } interface BB { void method2 () ; } interface CC extends BB ,AA { }
package cn.xpshuai.java5;public class Java8Test { public static void main (String[] args) { SubClass sub = new SubClass(); CompareA.method1(); sub.method2(); sub.method3(); } } class SubClass extends SuperClas implements CompareA ,CompareB { @Override public void method2 () { System.out.println("compareA:上海222222" ); } public void myMethod () { method3(); super .method3(); CompareA.super .method3(); CompareB.super .method3(); } }
内部类(用的少)
一种类成员
package cn.xpshuai.java5;public class InnerClassTest { public static void main (String[] args) { People.Food food = new People.Food(); food.show(); People people = new People(); People.Food2 food2 = people.new Food2 ("大白菜" ) ; food2.show(); } } class People { String name; int age; public void eat () { System.out.println("people eat" ); } static class Food { String name; int age; public void show () { System.out.println("food1" ); } } class Food2 { String name; public Food2 (String name) { this .name = name; } public void show () { System.out.println(name + "food22" ); } public void display (String name) { System.out.println(name); System.out.println(this .name); System.out.println(People.this .name); } } public void method () { class AA { } } { class BB { } } public People () { class CC { } } public Comparable getComparable () { class MyComparable implements Comparable { @Override public int compareTo (Object obj) { return 0 ; } } return new MyComparable(); } }
局部内部类使用注意点:
public class Test { public void method () { int num = 11 ; class AA { public void show () { System.out.println(num); } } } }
内容逻辑有些混乱,仅为个人学习笔记……