1 面向对象是模块化设计,面向过程是解决问题。
(1)面向对象的特点:
封装性:内部的操作对外部而言不可见
继承性:在上一辈的基础上继续发展
多态性:这是最重要 的环节。
(2)面向对象的开发分为三个阶段:OOA(面向对象分析),OOD(面向对象设计),OOP(面向对象编程)
(3)类与对象的定义
类与对象是面向对象设计的核心所在,是所有概念的基础。类本身属于引用数据类型,所以类的使用上会牵扯到内存的分配问题。
(4)引用类型的最大特征在于内存的分配操作,只要有new这个关键字出现,就只有一个解释:开辟内存(内存是不可能无限开辟的,所以这个时候所谓的性能调优,调整的就是内存问题)。
(5)对象内存分析
引用类性指的是内存空间的操作。内存空间包括堆内存空间(保存真正的数据,堆内存保存对象的属性信息),栈内存空间(保存的堆内存的地址,即堆内存的操作权)等。
如下图:
(6)引用传递的初步分析
引用的本质在于别名,而这个别名只不过放在了栈内存中。即一块堆内存可以被多个栈内存所指向。
示例:观察引用传递
class Person
{
String name;
int age;
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
Person per1=new Person();
per1.name="小于子";
per1.age=30;
//此步骤就是引用传递的操作
Person per2=per1;//采用同样的类型接受
per2.name="狗剩";//设置名字
per1.info();
}
}
结果:naem=狗剩,age=30
看下图的分析:
示例:观察引用传递2
class Person
{
String name;
int age;
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
Person per1=new Person();
Person per2=new Person();
per1.name="小于子";
per1.age=30;
per2.name="张三";
per2.age=20;
//此步骤就是引用传递的操作
per2=per1;//采用同样的类型接受
per2.name="狗剩";//设置名字
per1.info();
}
}
结果同上。观察此时的内存分析图:
(7)private封装(可以用private进行封装,但不是说封装只能用private进行)
class Person
{
String name;
int age;
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
Person per1=new Person();
per1.name="小于子";
per1.age=-30;
per1.info();
}
}
上述代码中不会报错,但是test中的per1会调用Person中的age,这就会造成年龄没有经过检测机会直接使用。
可以加上private封装,如下代码:
class Person
{
private String name;
private int age;
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
public static void main(String[] args) {
Person per1=new Person();
per1.name="小于子";
per1.age=-30;
per1.info();
}
}
此时运行就会出现错误,因为在类Test中的per1不能直接访问类Person中的name与age属性了。所以此时我们就可以使用setter和getter方法,这样就可以进行调用。如下代码:
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) {
if(age>0&&age<150)
{
this.age = age;
}
age=0;
}
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
public static void main(String[] args) {
Person per1=new Person();
per1.setName("张三");
per1.setAge(-200);
per1.info();
}
}
结果:name=张三,age=0
如果不在setAge中进行判断,那么结果是:name=张三,age=-200
可以看到,我们在setAge中进行了对age的判断。因为我们队name与age进行了封装,所以外部不能进行访问,但是info()方法和name与age是同一个类的,所以可以进行调用,同时info是public的,所以可以被Test类中的per1调用。
注意:以后类中的属性一定用private进行封装,如果被封装的属性被外界调用,那么就要定义相应的setter与getter方法。或者说可以不管是否调用都写这2个方法。
(8)构造方法
所谓的构造方法就是在使用new关键字实例化新对象的时候来进行调用的操作方法。
构造方法原则:方法名称必须与类名称相同,构造方法没有返回值类型声明,同时一个类中必须至少有一个构造方法,如果没有,则会自动生成一个无参的,什么都不做的构造方法。但是,需要注意的是,如果已经定义了一个构造方法,则将不会自动生成无参的构造方法,如下代码:
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) {
if(age>0&&age<150)
{
this.age = age;
}
age=0;
}
public Person(String name,int age)
{
System.out.println("--------");
}
public void info(){
System.out.println("name="+name+",age="+age);
}
}
public class Test {
public static void main(String[] args) {
Person per1=new Person();//因为已经定义构造方法了,所以不会自动生成无参的构造方法了,所以错误
per1.setName("张三");
per1.setAge(-200);
per1.info();
}
}
结果:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The constructor Person() is undefined
at 数组的定义与使用.Test.main(Test.java:42)
改正:
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) {
if(age>0&&age<150)
{
this.age = age;
}
age=0;
}
public Person(String name,int age)
{
this.name=name;
setAge(age);//
}
public void info()
{
System.out.println("name="+name+",age="+age);
}
}
public class Test {
public static void main(String[] args) {
Person per1=new Person("张三",-20);
per1.info();
}
}
结果:
name=张三,age=0
总结:构造方法最主要的作用就是为类中 的属性初始化。setter不仅有设置属性的作用,还可以修改属性。比如:Person per1=new Person("张三",-20);之后再写per1.SetName(“李四”);最后输出结果的名字就变成了李四。