java面向对象学习的三条主线:
Java类和类的成员:属性Field、方法Method、构造器Constractor;代码块、内部类面向对象三大特征:封装性、继承性、多态性、(抽象性)其他关键字:this、super、static、final、abstract、interface、package、import等面向对象OOP与面向过程POP对比:
面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
①打开冰箱
②抬起大象,放进冰箱
③关上冰箱门
面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
人{
打开(冰箱){
冰箱.打开();
}
抬起(大象){
大象.进入(冰箱);
}
关闭(冰箱){}
}
冰箱{
打开(){}
关闭(){}
}
大象{
进入(冰箱){}
}
类是对一类事务的描述,是抽象的、概念上的定义
对象是实际的该类事务的每个个体,因此也成为实例(instance)
面向对象设计的重点是类的设计。
类的设计就是类的成员的设计。
属性(field):对应类中的成员变量、域、字段行为:对应类中的成员方法(method)、函数如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的);意味着,如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
对象内存解析
堆(Heap):存放对象实体栈(Stack):存储局部变量(方法中的变量都是局部变量)方法区(Method Area):类信息、常量、静态变量、即时编译器编译后的代码对于不定义对象的句柄,直接调用这个对象的方法。这样的对象就叫做匿名对象。
比如:System.out.println(new Person().shout()) 直接输出新new的对象的方法
System.out.println((new Person().name)) 直接输出新new的对象的属性(默认name=null,也可以使用带有参数的构造器进行赋值:System.out.println(new Person(“jiwei”, 24)))也可以输出属性。
属性(成员变量) VS 局部变量
相同点:
1 定义变量的格式:数据类型 变量名 = 变量值2 先声明,后使用3 变量都有其作用域不同点:
1 在类中声明的位置不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2 关于权限修饰符的不同
属性:可以在声明属性的时候,指明其权限,使用public、private、缺省、protected等权限修饰符
局部变量:不可以使用权限修饰符
3 默认初始化值的情况
属性:根据其类型都有默认初始化值:整型(byte short int long)0、浮点型(float double)0.0、字符型(char)0、引用数据类型(类 数组 接口)null
局部变量:没有默认初始化值,意味着调用局部变量时一定显示赋值,形参在调用时赋值即可。
4 在内存中加载的位置不同
属性:加载的到堆空间(非static)
局部变量:加载到栈空间
成员变量(属性)和局部变量的内存解析:
对象属性的默认初始化值:
方法描述类应该有的功能。
分类:
无返回值有返回值无形参void 方法名(){}返回值类型 方法名(){}有形参void 方法名(形参列表){}返回值类型 方法名(形参列表){}方法的声明:权限修饰符 返回值类型 方法名(形参列表){
方法体}
关于权限修饰符:private 、public 、缺省、 protected
关于返回值类型:有返回值的、没返回值的
有返回值的:需要return关键字返回指定类型的变量或常量,一定需要返回
无返回值的:声明时需要使用void来表示,如果用“return”是结束方法的作用
方法名:属于标识符,见名知意
形参列表:方法可以声明0个,1个或多个形参。
return关键字的使用:
方法的使用:可以调用当前类的属性或方法;方法中不可以定义其他的方法编译完源代码以后,生成一个或多个字节码文件。
我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。
虚拟机栈,即为平时提到的栈结构,我们将局部变量存储到栈结构中。
堆,new出来的结构(比如数组、对象)。对象的属性(非static)
内存解析案例:定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可
“两同一不同”:同一个类、同一个方法名,参数列表不同(参数个数、参数类型)
public class OverLoadTest { public static void main(String[] args) { OverLoadTest test = new OverLoadTest(); test.getSum(1,2); } //如下的4个方法构成了重载 public void getSum(int i,int j){System.out.println("1");} public void getSum(double d1,double d2){System.out.println("2");} public void getSum(String s ,int i){System.out.println("3");} public void getSum(int i,String s){System.out.println("4");} //如下的3个方法不能与上述4个方法构成重载 // public int getSum(int i,int j){return 0;} // public void getSum(int m,int n){} // private void getSum(int i,int j){} }jdk5.0新增特性,允许直接定义能和多个实参相匹配的形参。通常用在与数据库交互的时候!
具体使用:
格式:方法名(参数的类型名 …参数名)
当调用可变个数参数的方法时,参数个数可以是0个、1个。。。
可变个数形参的方法与本类方法中方法名相同,形参个数不同的方法之间构成重载
可变个数形参的方法与本类中方法名相同,形参类型也相同的数组,不能共存。
可变个数形参必须声明在末尾!并且也只能存在一个可变个数形参。
public void show (int i , String … strs)
public class MethodArgsTest { public static void main(String[] args) { MethodArgsTest test = new MethodArgsTest(); test.show(19); test.show("jiWei"); test.show("jiWei", "sunYan", "liuZiXin"); } public void show(int i){ System.out.println(i); } public void show(String s){ System.out.println(s); } public void show(String...s){ System.out.println(s); for (int i = 0; i < s.length; i++) { System.out.println(s[i]); } } }关于变量的赋值
如果变量是基本数据类型,此时赋值的是变量所保存的数据值如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值关于方法的形参的传递机制:值传递
形参:方法定义时,声明的小括号内的参数实参:方法调用时,实际传递给形参的数据案例6(!!!)
需要从内存中方法的入栈出栈进行分析!!
把该隐藏的隐藏起来,把该暴露的暴露出来。
具体表现为信息的隐藏:
通过将数据声明为私有的private,再提供公共的public方法:**getXxx()和setXxx()**实现对属性的操作。 class Animal { private int legs;// 将属性legs定义为private,只能被Animal类内部访问 public void setLegs(int i) { // 在这里定义方法 eat() 和 move() if (i != 0 && i != 2 && i != 4) { System.out.println("Wrong number of legs!"); return; } legs = i; } public int getLegs() { return legs; } } public class Zoo { public static void main(String args[]) { Animal xb = new Animal(); xb.setLegs(4); // xb.setLegs(-1000); //xb.legs = -1000; // 非法 System.out.println(xb.getLegs()); } }构造器或者成为构造方法
构造器又分为了无参构造器和有参构造器。
系统默认提供一个隐式的无参构造器;也可以自己显式定义多个构造器(有参或无参)
特点:
具有和类相同的名称
不声明返回值:public Person(){}
修饰符有:不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值。
创建对象;给对象进行初始化!
比如:Order o = new Order(); Person p = new Person(“Peter”,15);
我的理解就是,就是初始化不同类型的对象,有的对象初始有属性,有的初始没有属性。
案例1:
public class Animal { private int legs; //无参构造器 public Animal(){ //构造器内初始化属性,也就是说初始化对象的时候,默认animal就有4个legs legs = 4; } public void setLegs(int i){ legs = i; } public int getLegs(){ return legs; } } public class AnimalTest { public static void main(String[] args) { Animal animal = new Animal(); System.out.println(animal.getLegs());//4 } }案例2:
public class PersonTest { public static void main(String[] args) { Person person = new Person(); System.out.println(person.getAge());//因为在构造器内初始化了age=18 person.setAge(29);//使用setAge重新设置age = 29 System.out.println(person.getAge()); System.out.println(person.getName());//string类型默认值为null person.setName("jiwei"); System.out.println(person.getName()); } } public class Person { //私有属性 private String name; private int age; //无参构造器,设置age默认值为18 public Person(){ age = 18; } public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setAge(int age){ this.age = age; } public int getAge (){ return age; } }案例3:有参构造器和无参构造器对比:
//测试类 public class TriAngleTest { public static void main(String[] args) { //使用无参构造器实例化一个三角形 TriAngle angle = new TriAngle(); angle.setBase(5.0); angle.setHeight(10.0); System.out.println(angle.findArea()); System.out.println("=============="); //使用有参构造器实例化一个三角形 TriAngle angle1 = new TriAngle(6.0, 3.0); System.out.println(angle1.findArea());}} //三角形类 public class TriAngle { private double base;//底 private double height;//高 //无参构造器 public TriAngle(){} //有参构造器 public TriAngle(double base, double height){ this.base = base; this.height = height;} //get、set方法 public double getBase() { return base;} public void setBase(double base) { this.base = base; } public double getHeight() { return height;} public void setHeight(double height) { this.height = height; } /** * @Author jiwei * @Description //TODO 计算三角形面积 * @return 三角形的面积 **/ public double findArea(){ return height*base*0.5;}}举例:
public class Person { private String name; private int age; private Date birthDate; public Person(String n, int a, Date d) { name = n; age = a; birthDate = d; } public Person(String n, int a) { name = n; age = a; } public Person(String n, Date d) { name = n; birthDate = d; } public Person(String n) { name = n; age = 30; } }JavaBean指符合如下标准的Java类:
类是公共的有一个无参的公共的构造器有属性,且有对应的get、set方法JavaBean示例:
public class JavaBean { private String name; // 属性一般定义为private private int age; public JavaBean() { } public int getAge() { return age; } public void setAge(int a) { age = a; } public String getName() { return name; } public void setName(String n) { name = n; } }它在方法内部使用,即这个方法所属对象的引用;
它在构造器内部使用,表示该构造器正在初始化的对象
this 可以调用类的属性、方法和构造器
package语句作为Java源文件的第一条语句,指明该文件中定义的类所在
的包。(若缺省该语句,则指定为无名包)。它的格式为:
package 顶层包名**.**子包名 ;
举例:
pack1\pack2\PackageTest.java package pack1.pack2; //指定类PackageTest属于包pack1.pack2 public class PackageTest{ public void display(){ System.out.println("in method display()"); } }包对应于文件系统的目录,package语句中,用 “.” 来指明包(目录)的层次;
包通常用小写单词标识。通常使用所在公司域名的倒置:com.atguigu.xxx
import语句告诉编译器到哪里去寻找类。
语法格式:
import 包名**.** 类名**;**