`
付绍高
  • 浏览: 37015 次
  • 性别: Icon_minigender_1
  • 来自: 江西临川
社区版块
存档分类
最新评论
阅读更多
浅析面向对象的编程思想
面向对象的编程思想是现在编程的主要思想。其优点有很多,特别的是相比较面向过程的编程。学够一点编程语言的的程序员都知道:面向对象的编程的三大特性(封装,继承,多态)。

下面谈谈我对面向对象的编程思想的理解
 
1. 封装
从表面上的理解:无非是将一个一个的东西装起来,就像是将给一个物体包装是的。
从语言的角度理解:就是将有意义的事物转换成类。类是封装的载体,为了真正达到封装的效果,java 语言中采用了一定的修饰符来控制不同类间的访问。
Public:
1,从字面上的理解是:公开的。
2.这个访问权限的修饰符是在java中的修饰符中访问权限最大的,最大的访问权限可以在不同的包中。
Private:
      1.从字面的理解是:私有的
2,这个访问修饰符石在java中修饰符中权限最小的,最大的权限是同一个类中,很好的保证了类的私有属性(不对外公开);
Deflaut;
1. 从字面的理解是:默认的(即没有填写任何的访问修饰符)
2. 这个访问的修饰符最大的权限是包级的,但是在他的子类
Protected:
可直接访问

修饰 同一类中 同一包中 不同包的子类中 其他
private Yes      
默认 Yes Yes    
protected Yes Yes Yes  
public Yes Yes Yes Yes


注解:一般的事物主要包括属性和行为这两个特性。属性在类中的名称是:成员变量。类的行为在类中的名字是:成员方法。其实我们日常生活中所看见的都是类的实例;(属性就是我们人类在感觉上暂时不可以变的东西,象人的体重,身高)
       简单的将一个事物抽象成为一个类
          大雁往南飞
      分析:大雁就是一个实例。我们可以大雁的上一级概念上联想下。大雁的上一级不就是鸟嘛,然而鸟类共有的属性是什么呢?鸟类肯定有翅膀。那么翅膀就是鸟类的一个属性 。那个描述上中的方法是什么呢?
           大雁往南飞中的飞就是一个方法。
       Public class Bird()
{
    Int numWing;//翅膀的个数
   Public void fly()
    {
     System.out.println(“鸟在飞”);
}
}         
     上面的分析只是简单的分析,在开发中一般要根据名词来划分类,不是每个的属性和行为都要写上,对我们的程序有意义的属性和行为才是我们关注的重点  

2. 继承(通过extends这个关键字)
            继承的概念拿一个形象点的例子来说就是:你可以从你的父亲那里继承他的财产等。同样我们的程序也有这个方面的优点。这个观想的提出很打程度上解决了我们程序上的冗余
          1.谈谈类的构造函数
              构造函数的作用就是对本类属性的初始化
               Public class Bird()
                 {
                     Int numWing;
                     Public Bird(int numWing)
                      (
                       This.numWing=numWing;
)
}
              注意:构造函数的名字要和类的名字相同,没有返回值的类型
                   在创建对象的时候必须要调用我们的构造函数(只是构造函数的形式不同,默认的是调用我们的无参数的构造函数。当然也可以调用我们的有参数的构造函数,这个就用到我们的重载的概念)
2.谈谈this 这个关键字的用法
               This 这个关键字就是对本类的一个对象。对象就是我们类的一个实例,就像我们多看见的物体。只是它只是具体类的对象而已。
               但是这个关键字的提出很有它的意义:特别是在属性的名字重复的时候,这个关键字很有意思
              例如:上面的程序
                   形参是numWing 但是类的属性也是numWing 这个时候我们可以引入这个关键字来写
                        This.numWing=numWing;
                   This 就是类的实例,谁初始化这个this就是这个类的实例
               然而还有一点的不同就是可以这样书写:return this; 返回这个类的对象
          3.谈谈super这个关键字
          我的理解super关键字就是对父类对象的隐式引用
          可以调用父类的非私有的
       注意:this.和super在构造构造函 数中必须是第一个语句;
        4.谈谈static 这个关键字
           这个关键字可以修饰我们属性和方法。这个属性和方法是属于我们的类的不是属于我们的对象的。但是访问static可以有两种方法
1. 类名+(static变量或者是方法的名称)
2. 对象+(static变量或者是方法的名称)
Public class Bird()
{
  static Int numWing;
public static void fly()
  {
   System.out.println(“在飞”);
}
Public static void main(String [] args)
  {
  Bird.fly();
  System.out.println(Bird.numWing);
  Bird afu=new Bird();
   Afu.fly();
    System.out.println(afu.numWing);
}
}
           注意:我们的继承要有一定的意思:我的意思是说子类一定要有一些独特的属性和方法。当然也可以覆盖父类的属性和方法 (这个要用到我们多态的思想)
     
            

         
3. 多态(在程序中主要体现程序上的重写和重载这两个方面上)
1. 谈谈我对重载概念的理解
重载要满足两个条件:1方法名相同
                    2参数列表不同
                    3.返回值不作要求,必须要本类中(因为在java中返回值是可以忽略的)
Public class Bird()
{
   Int numWing;
   Public Bird(int numWing)
      {
This.numWing=numWing;
}
Public Bird()
{
  System.out.println(“作者的名字是afu”);
}
}
简单的解析下上面的程序:这个函数中只是简单的对我们类的构造函数进行了重载。程序中会根据我们的在new对象的时候的参数的不同,进行初始化的工作
2 谈谈我对重写的理解
   重写:主要发生在程序的父类和子类自间
      必须满足的条件:1 继承
                      2 重写的方法的名称要和被重写的方法的名称相同,参数列表相同,访问权限要大于或者等于被从写的方法,返回值要要小于或者等于被重写的返回值,异常要小于被重写的方法(两同两小一大),方法体要不同(不然的话就失去重写的意义了)
Public class Bird()
  {
     Int numWing;
     Public Bird(int numWing)
        {
          This.numWing=numWing;
}
Public void fly()
  {
       System.out.println(“鸟在飞”);
}

}
  Public  class WideGoose extends Bird( )
  {
   Public void fly()
      {
      System.out.println(“wide goose 在飞”)
}
}
最简单的重写方式就是copy上面要写的方法,在方法体里面修改(建议用这个方式),不然的话很容易就不是重写父类的方法而是在子类中重新声明这个方法
(认真去体会这个不同)但是重写无法重写父类的构造函数(听陈老师说:这个很可能出现在我们的面试题上面)。
3谈谈我对多态的理解
  上课的时候,陈老师只是概括的讲下多态的感念,谈谈我对多态的理解,
多态必须满足三个条件:1,继承
                    2 重写
                    3 子类对象指向父类的引用
这个地方又引入了一个概念向上转型和向下转型的概念
1. 向上转型
子类对象指向父类的引用
简单的将陈老师上的例子讲下(人和男人的问题)
男人可以是人
Public class Person()
{
   Public void eat()
    {
     System.out.println(“人吃饭”)
}
Public  void  sleep()
{
   System.out.println(“人睡觉”)
}
  Public static voia main(String [] args)
   {
     System.out.println(“我是afu”)
}
}

-------------------------子类------------------------

Public class Man extends Person
{
   Public void eat()
    {
    System.out.println(“afu喜欢吃鸡块”)
}
Public static void main(String [] args)
  {
    Person afu=new Man();//子类对象指向父类的引用
   
}
}
2. 向下转型
向下转型很容易发生错误
  (人不一定男人) 在程序上一定要去判断这个转变是不是成立;用istanceof 去判断


谈谈我(afu)对变量的理解:
  除了值变量外,其他的都是引用变量(值内存分布在栈空间中,引用变量分配在堆内存中,可以简单的这样理解)。
谈谈我对final 关键字的理解
Final这个关键字,我只是想说注意这个关键字对值变量和引用变量的不同。(认真的体会我说的不同,细节成就失败与成功)。
谈谈我对abstract这个关键字的理解
这个关键字不可以了static关键一起使用,简单的理解就像我们生活之中的模版类,只是有方法的声明,没有具体的实现过程,当然这个里面也可以有构造函数,这里的构造函数只是让子类的去初始化父类,并没有其他的意义
简单的解释下为什么
  因为static修饰的是我们类的变量和方法,然而adstract 这个关键出现的目的就是让我们子类重写父类的方法,来实现父类的方法,然后通过我们的多态的思想,转到我们子类的重写的方法
谈谈我对interface这个关键字的理解
在面向对象的思想中,interface是最抽象的一个;interface 就是抽象类的更加抽象的一层。
简单的理解下:如同我们在日常生活中在产品上看见的通过Iso900认证一样,其中iso900只是我们产品在生产产品中的标准一样。可以将我们的interface简单的理解成我们的标准
谈谈我对==与equals的不同
“==“这个是比较两个变量的引用是否相等,“equals”是比较两个变量的值是否想的。其实,他们并不知道为什么这样。什么时候相等和不相等。我将简单的阐述下为什么?
其实很简单的事情
父类(Object )中的equals方法其实就是比较两个变量的引用是否相等,只是其他的类型重写了父类的equals方法,具体的要看重写的类中的equals中的方法,这个地方也体现了多态的思想(认真的体会这个地方),简单我就拿String类中的equals 简单的解释下:
当没有重写父类的equals方法的时候“==”与“equals”方法比较的都是比较变量的引用是不是相等,这两的修饰符返回的结果是相等的,但是String类重写了equals方法,比较的是两个变量的值是不是相等,他会比较我们的变量的每个字符序列是不是相等(具体的实例就不写了)







以上是我对面向对象编程思想的理解,望陈老师将我理解上错误的地方给与更正
                                                     奋斗十班  afu





                              容器总结
  容器这章,我觉得只要在自己的大脑中要形成这样的一张图就是
               
                 

要记着其中的Collection,List,Map,Set 这里边都是接口,其中Collection是其他的父接口,ArrayList,HashMap,HashSet分别是List,Map,Set中的实现类,记住容器中丢进去的都是对象,除了用到hash的其他比较相等实质是Equals方法,用到hash的容器类比较的是Equals 和相应的hashCode是不是相等,List 和Set 有点不同的地方就是List中可以装两个相等的对象,而Set不可以装两个相等的对象
用到hash 的使用一定要重写Equals方法和hashCode 方法,这样才能保证其中的hash值和相应的对象的相等
其中的Collections 是保证线程的安全设置的。Collections是个类
在这里我来说下,其中的Map接口着个比较特殊,他有两个属性,分别是key和Value
Key其中就是储存着我们添加的对象的索引值,其实质是个Set来装我们的索引的,Value中装的是我们的要添加的对象,在遍历的时候,其方法是这样的
Set<key的类型>名字=HashMap的对象.keySet();
Interator it=上面key的名字.iterator();
While(it.hasNext())
{


}
在遍历我们的List 和Set 也可以不用我们的遍历器,直接使用我们的增强的for循环,下面的代码演示了for循环来遍历我们的容器,其实质是增强的for是从写了我们的Iterator遍历器
ArrayLIst,HashMap,HashSet都是基于我们的线程不安全的,一定要保证我们的线程安全,要用Collections 来控制

  package org.fendou;
import java.util.*;
public class Student {
private String name;
private String sex;
private int age;
public Student()
{

}
public Student(String name,String sex,int age)
{
this.name=name;
this.sex=sex;
this.age=age;
}
public void setName(String name)
{
this.name=name;
}
public void setSex(String sex)
{
this.sex=sex;
}
public void setAge(int age)
{
this.age=age;
}
public String getName()
{
return this.name;
}
public String getSex()
{
return this.sex;
}
public int getAge()
{
return this.age;
}
public boolean equals(Object obj)
{
if(this==obj)
{
return true;
}
if(obj!=null&&this.getClass()==obj.getClass())
{
Student afu=(Student)obj;
if(this.getName().equals(afu.getName())&&this.getSex().equals(afu.getSex())&&this.getAge()==(afu.getAge()))
{
return true;
}
}
return false;
}
public int hashCode()
{
return this.getName().hashCode()*3+this.getSex().hashCode()*5+this.getAge();
}
public static void main(String [] aggs)
{
/* Map<Integer,Student>student=Collections.synchronizedMap(new HashMap<Integer,Student>());
student.put(new Integer(1), new Student("afu","male",21));
student.put(new Integer(2), new Student("afu","male",21));
       Set<Integer> it=student.keySet();
       Iterator stu=it.iterator();
       while(stu.hasNext())
       {
       Object afu=stu.next();
       System.out.println(student.get(afu).getName()+"  "+student.get(afu).getSex()+"  "+student.get(afu).getAge());
       }*/
/*List<Student>student=Collections.synchronizedList(new ArrayList<Student>());
student.add(new Student("afu","male",21));
student.add(new Student("afu","male",21));
for(Student afu:student)
{
System.out.println(afu.getName()+afu.getSex()+afu.getAge());
}*/
       Set<Student>student=Collections.synchronizedSet(new HashSet<Student>());
       student.add(new Student("afu","male",21));
       student.add(new Student("afu","male",21));
       for(Student afu:student)
       {
       System.out.println(afu.getName()+"  "+afu.getSex()+afu.getAge());
       }

}


}
































线程的总结
   在说之前,我先讲个故事:新编版的龟兔赛跑
      兔子和乌龟赛跑,其中的裁判员是老鼠,老鼠法令之后才跑,但是老鼠也跑,他们各自的目标就是将自己的任务完成,他们跑的路线不同,兔子和乌龟就是我们自己定义的线程,老鼠是我们的main主线程
     其实线程这张很好理解,关键是有些人对操作系统不是很了解,这里简单说说下
  线程是Cpu分配的最小资源,进程是操作系统中的最小资源
     简单说说下进程的分配资源的过程是这样的
       
在java中实现我们的线程的过程,有两种方法;
1. 继承我们的Thread这个类,也要重写我们的Run方法,没有必要在我们的程序中重写,getName这个方法,因为我们的Thread 重写了这个方法,我们直接掉就是了

public class TThread extends Thread{
private int i;
public TThread(String name)
{
super(name);
}
public void run()
{
for(;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+"  "+i);
}
}
public static void main(String [] args)
{
TThread afu=new TThread("新建线程1");
afu.start();
}

}
2. 实现我们的Runnable接口,其中有一个run方法是抽象方法,我们必须重写run方法,将我们要执行的放到里面
Thread类就是我们Runnable实现类
package org.fendou;
public class TestThread implements Runnable{
private int i;
private String name;
public TestThread()
{

}

public TestThread(String name)
{
this.name=name;

}
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}

public void run()
{
for(;i<100;i++)
{
System.out.println(this.getName()+"  "+i);
}

}
public static void main(String [] args)
{
Runnable afu1=new TestThread("新建线程1");//这里值得我们注意
Thread  afu=new Thread(afu1);  //这里值得我们注意
afu.start();

}

}
简单解释下陈老师上课讲的死锁的问题,构成死锁的充分条件就是构成循环,(这个地方的循环好像是不对);简单解释下下面的图:你等我去玩,你等我去玩,其结果就是我们都在互相的等待



package org.fendou;

public class ThreadDead  extends Thread{
static Object t1=new Object();
static Object t2=new Object();
int flag;
public ThreadDead(String name)
{
super(name);
}
public void run()
{
if(flag==1)
{
synchronized(t1)
{
System.out.println(Thread.currentThread().getName()+"进入t1");

}
try{
Thread.sleep(1000);
}catch(InterruptedException s)
{
s.printStackTrace();
}
synchronized(t2)
{
System.out.println(2);
}
}
if(flag==2)
{
synchronized(t2)
{
System.out.println(Thread.currentThread().getName()+"进入t2");

}
try{
Thread.sleep(1000);
}catch(InterruptedException s)
{
s.printStackTrace();
}
synchronized(t1)
{
System.out.println(1);
}
}
}
public static void main(String [] args)
{
ThreadDead afu=new ThreadDead("新建线程1");
ThreadDead afu1=new ThreadDead("新建线程2");
afu.flag=1;
afu1.flag=2;
afu.start();
afu1.start();
}


}
解释下上面的程序,其实老师是利用一个flag变量来控制我们的线程,这个控制可以使我们的一个线程变成两个线程,其实就是一个run方法






package org.fendou;

public class Account {
private String accountNo;
private double balance;
public Account()
{

}
public Account(String accountNo,double balance)
{
this.accountNo=accountNo;
this.balance=balance;
}

public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}


}



package org.fendou;
import java.util.*;
public class DrawAccount implements Runnable{
private Account drawAccount;
private double drawBalance;
private String name;
public DrawAccount()
{

}
public DrawAccount(String name,Account drawAccount,double drawBalance)
{
this.name=name;
this.drawAccount=drawAccount;
this.drawBalance=drawBalance;
}
public void setName(String name)
{
this.name=name;
}
public String  getName()
{
return  this.name;
}
public Account getDrawAccount() {
return drawAccount;
}
public void setDrawAccount(Account drawAccount) {
this.drawAccount = drawAccount;
}
public double getDrawBalance() {
return drawBalance;
}
public void setDrawBalance(double drawBalance) {
this.drawBalance = drawBalance;
}
/*public void run()
{
synchronized(drawAccount)
{

if(this.drawAccount.getBalance()>this.drawBalance)
{
System.out.println(this.getName()+"恭喜你取钱成功");
try{
Thread.sleep(1000);
}catch(InterruptedException s)
{
s.printStackTrace();
}
this.drawAccount.setBalance(this.drawAccount.getBalance()-this.drawBalance);
System.out.println("您现在的金额是"+this.drawAccount.getBalance());
}
}
}*/
public void run()
{

}
public synchronized void draw()
{
if(this.drawAccount.getBalance()>this.drawBalance)
{
System.out.println(this.getName()+"恭喜您取钱成功");
try{
Thread.sleep(1000);
}catch(InterruptedException s)
{
s.printStackTrace();
}
this.drawAccount.setBalance(this.drawAccount.getBalance()-this.drawBalance);
System.out.println("您现在的余额是"+this.drawAccount.getBalance());
}
}
public static void main(String [] args)
{
Account afu=new Account("1111",9000);
DrawAccount afu1=new DrawAccount("新建线程1",afu,6000);



}


}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics