Java之一篇关于面向对象

面向对象,呃,别给我说程序员找不到对象,那是windows才会出现的情况~~~就简单记下笔记什么的吧。 1、关于定义和赋值之前总是搞混淆,说到底是没有搞清楚。

  面向对象,呃,别给我说程序员找不到对象,那是windows才会出现的情况~~~

  就简单记下笔记什么的吧。

 1、关于定义和赋值

  之前总是搞混淆,说到底是没有搞清楚。

shit bigOne=new shit();

 类型   变量名   定义

  所以应该是先写后面——定义——new 类名();然后是前面,赋值给一个变量;然后最前面,该变量的数据类型,这里,数据类型就是该类。

2、局部变量和成员变量

  遵循就近原则,即局部变量和成员变量重复时,以局部变量为准。

3、关于构造方法

  其实上面定义对象的时候,最后面那个不是变量,不是类,是该类的构造方法!!!

  所以有参的对象定义,也就是在有参的构造函数的调用。

  所以可以直接通过有参构造函数进行输入,同时可以进行输入控制——安全性,正确性等。

  另外,关于有参和无参并存:

package imooc2;

public class telephone {
    //属性
    double size;
    String color;
    double cpu;
    double price;
    //方法
    void sendMessage(){
        System.out.println("Shit!"+size+color+cpu+price);
    }
    public telephone(){
        System.out.println("无参构造方法执行!");
    }
    public telephone(double sizeIn,String colorIn,double cpuIn,double priceIn){
        size=sizeIn;
        color=colorIn;
        cpu=cpuIn;
        price=priceIn;
        System.out.println("有参构造方法执行");
    }

}
package imooc2;

public class initialTelephone {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        telephone phone = new telephone(1,"black",2.3,1500);
        phone.sendMessage();
        phone.color="white";
        phone.cpu = 1.3;
        phone.sendMessage();
        telephone phone2 = new telephone();
        phone2.sendMessage();
    }
}

 4、关于静态变量

  静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收。

  同样,静态方法也会有特殊情况:

  

与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如:

运行结果:

需要注意:

1) 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:

如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:

2) 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:

3) 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。如:

 

与静态变量一样,我们也可以使用 static 修饰方法,称为静态方法或类方法。其实之前我们一直写的 main 方法就是静态方法。静态方法的使用如:

运行结果:

需要注意:

1)静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:

如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。如:

2) 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量,如下所示:

3) 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。

public class HelloWorld {
    
    // 定义静态变量score1
    static int score1 = 86;
    // 定义静态变量score2
    static int score2 = 92; 

    // 定义静态方法sum,计算成绩总分,并返回总分
    public   static  int sum() { 
      int sum = score1+score2;
      return sum;      
    }

    public static void main(String[] args) {        
        // 调用静态方法sum并接收返回值
        int allScore = HelloWorld.sum();        
        System.out.println("总分:" + allScore);
    }
}

 


5、关于静态初始化块

  这个我也是第一次知道,有点好玩,也是初始化块——》静态初始化块的

public class HelloWorld {
    
    String name; // 声明变量name
    String sex; // 声明变量sex
    static int age;// 声明静态变量age
    
    // 构造方法
    public  HelloWorld() { 
        System.out.println("通过构造方法初始化name");
        name = "tom";
    }
    
    // 初始化块
    { 
        System.out.println("通过初始化块初始化sex");
        sex = "男";
    }
    
    // 静态初始化块
       static { 
        System.out.println("通过静态初始化块初始化age");
        age = 20;
    }
    
    public void show() {
        System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
    }
    
    public static void main(String[] args) {
        
        // 创建对象
        HelloWorld hello = new HelloWorld();
        // 调用对象的show方法
        hello.show();
        
    }
}

  通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。

  需要特别注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量

 6、关于封装

  对象的三大特性:封装、继承和多态!

  封装:封装是个动词,动词就有对象,这里的对象就是对象,也就是把对象进行封装。什么叫做对象的封装呢?就是外部不能直接访问内部属性。类比电子元器件的封装,也就是用户只能通过接口插口等对其进行访问,不能直接接触其中的元器件。

  好处自然不用说。

  另外,封装三大步:private属性——》set和get方法设定——》输入输出控制;

package imooc2;

public class telephone {
    //属性
    private double size;
    private String color;
    private double cpu;
    private double price;
    //方法
    public double getSize(){
        return size;
    }
    public void setSize(double sizeInput){
        size=sizeInput;
    }
    public String getColor(){
        return color;
    }
    public void setColor(String colorInput){
        color=colorInput;
    }
    void sendMessage(){
        System.out.println("Shit!"+size+color+cpu+price);
    }
    public telephone(){
        System.out.println("无参构造方法执行!");
    }
    public telephone(double sizeIn,String colorIn,double cpuIn,double priceIn){
        size=sizeIn;
        color=colorIn;
        cpu=cpuIn;
        price=priceIn;
        System.out.println("有参构造方法执行");
    }

}

 

7、关于包

  包也可以看成是一种封装,只不过对象是各种类,也就是说包是各种类的文件夹。

  包的存在是重名问题得到解决——比如你我都有一个姐姐,但定义一个类文件的时候,重名的是不能出现在同一个包的,所以有子包等概念出现。

  这里就可以有两个telephone.java;

  调用的话,就在头输入import即可

package com.imooc;
import com.imooc.second.telephone;

8、访问修饰符

一图以敝之

9、关于this关键字

  this表示当前对象,于是setter和getter中就经常使用this了。

  另外,eclipse中自带生成setter和getter。

  于是

public double getCpu() {
        return cpu;
    }
    public void setCpu(double cpu) {
        this.cpu = cpu;
    }

 10、关于内部类

  即类中类,关键就是用一个关键字Inner

//外部类HelloWorld
public class HelloWorld {
    
    // 内部类Inner,类Inner在类HelloWorld的内部
    public class Inner {
        
        // 内部类的方法
        public void show() {
            System.out.println("welcome to imooc!");
        }
    }
    
    public static void main(String[] args) {
        
        // 创建外部类对象
        HelloWorld hello = new HelloWorld();
        // 创建内部类对象
        Inner i = hello.new Inner();
        // 调用内部类对象的方法
        i.show();
    }
}

   内部类的存在原因是更好的封装

//外部类HelloWorld
public class HelloWorld{
    
    //外部类的私有属性name
    private String name = "imooc";
    
    //外部类的成员属性
    int age = 20;
    
    //成员内部类Inner
    public class Inner {
        String name = "爱慕课";
        //内部类中的方法
        public void show() { 
            System.out.println("外部类中的name:" + HelloWorld.this.name );
            System.out.println("内部类中的name:" +    name              );
            System.out.println("外部类中的age:" + age);
        }
    }
    
    //测试成员内部类
    public static void main(String[] args) {
        
        //创建外部类的对象
        HelloWorld o = new HelloWorld (); 
        
        //创建内部类的对象
        Inner inn =   o.new Inner()           ;
        
        //调用内部类对象的show方法
        inn.show();
    }
}

 

  以及静态内部类

//外部类
public class HelloWorld {
    
    // 外部类中的静态变量score
    private static int score = 84;
    
    // 创建静态内部类
    public static class SInner {
        // 内部类中的变量score
        int score = 91;
        
        public void show() {
            System.out.println("访问外部类中的score:" + HelloWorld.score );
            System.out.println("访问内部类中的score:" + score);
        }
    }

    // 测试静态内部类
    public static void main(String[] args) {
        // 直接创建内部类的对象
        SInner si = new SInner();
        
        // 调用show方法
        si.show();
    }
}

  以及方法内部类,也就是方法中定义内部类,有点繁琐,搞清楚调用的过程就行了 

//外部类
public class HelloWorld {
    
    private String name = "爱慕课";
    
    // 外部类中的show方法
    public void show() { 
        // 定义方法内部类
        class MInner {
            int score = 83;
            public int getScore() {
                return score + 10;
            }
        }
        
        // 创建方法内部类的对象
        MInner mi = new MInner();
        
        // 调用内部类的方法
        mi.getScore();
        
        System.out.println("姓名:" + name + "\n加分后的成绩:" + newScore);
    }
    
    // 测试方法内部类
    public static void main(String[] args) {
        
        // 创建外部类的对象
        HelloWorld mo = new HelloWorld();
        
        // 调用外部类的方法
        mo.show();
    }
}

 

 

11、关于继承

  就是子类继承父类的属性和方法,说白了就是代码复用,就是程序员懒省事儿,为了代码整洁所做的工作。

  需要注意父类的private是继承不到的。

  实际上初始化一个子类对象,是先初始化父类对象的属性和构造方法,然后是子类的属性和构造方法!

  可以使用super关键词调用父类的方法和属性,注意super无法在static的方法中调用,比如主函数。

12、关于重写

  重写,也是一个动词,对象就是方法,是父类的方法。

  就是子类对父类的方法不满意,重新书写该方法。

  需要注意的是重写要求函数投是要求完全相同的,才能实现重写。

13、final关键字

14、关于Object类

  所有类在没有强调父类时,默认的父类都是Object类!

  Object类中有两个常用到的方法,toString()和equals();前者默认返回对象地址信息,后者默认对比两个对象引用地址是否相同;

  由于对父类这两个方法不满意,所以我们在子类中进行重写;

  这两个特殊的重写,直接交给eclipse,方法和上面那个一样,结果如下

package com.jicheng;

public class Dog extends Animal {
    public int age=10;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)//引用地址
            return true;
        if (obj == null)//比较空值
            return false;
        if (getClass() != obj.getClass())//类对象,就是把类的情况作为对象,类的类型是否相同
            return false;
        Dog other = (Dog) obj;
        if (age != other.age)//属性值
            return false;
        return true;
    }

    public void eat(){
        
    }

    @Override
    public String toString() {
        return "Dog [age=" + age + "]";
    }
    
}

 主函数

package com.jicheng;

public class initial {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Dog dd=new Dog();
        System.out.println(dd);
        Dog dog = new Dog();
//        if(dog==dd){
        if(dog.equals(dd)){
            System.out.println("yes");
        }else{
            System.out.println("no");
        }

    }

}

 15、关于多态

  多态,一个形容词,就是说多种形态,那么形容的对象是?是对象。也就是说对象具有多种形态。

  那么,对象具有多种形态,其实说的是对象的引用和方法具有多种形态

  直观的看比较抽象,给出代码示例

package com.duotai;

public class initial {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Animal obj1 = new Animal();
        Animal obj2 = new Dog();//父类的引用可以指向子类的对象
        Dog obj3 = new Dog();
//        Dog obj4 = new Animal();//错误
        obj1.eat();
        obj2.eat();//同样是父类的引用,但指向不同结果不同,称为方法的多态
    }
}

 

 

package com.duotai;

public class Animal {
    public void eat(){
        System.out.println("Can eat");
    }
}

 

 

package com.duotai;

public class Dog extends Animal {
    public void eat(){
        System.out.println("Dog eats meat");
    }
}

 

16、关于引用类型转换

  这里出现了父类引用子类的情况,也就是说有引用类型转换的情况了。

  关于引用类型转换,分为向上转换/隐式转换和向下转换/强制转换;

  考虑向上转换为把水杯里的水倒回水壶,所以一般都是没有问题的;向下则相反,会出现问题,于是会有强制转换的需求。

package com.duotai;

public class initial {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Dog dog = new Dog();
        Animal animal = dog;//向上转换
//      Dog dog2 = animal;//直接的向下转换,不被允许
        Dog dog2 = (Dog)animal;//强制的向下转换,可以执行
        Cat cat = (Cat)animal;//同样可以执行,但会出现编译问题
    }
}

 

  所以,一般使用强制使用的,需要先进行判断,用instanceof

package com.duotai;

public class initial {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Dog dog = new Dog();
        Animal animal = dog;//向上转换
        if(animal instanceof Dog){
            Dog dog2 = (Dog)animal;
        }else{
            System.out.println("Shit");
        }
        if(animal instanceof Cat){
            Cat cat = (Cat)animal;
        }else{
            System.out.println("Shit");
        }
    }
}

 

17、关于抽象类

  说到引用类型转换,有一个常用的场景:抽象类。

  抽象对应具体,也就是说抽象的类;抽象类不关注子类的具体实现,只规定子类应该有什么样的方法!!

package com.chouxianglei;

public abstract class Telephone {
    public abstract void call();
    public abstract void message();
}

 

  子类应该继承它

package com.chouxianglei;

public class cellPhone extends Telephone {

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("键盘打电话");
    }

    @Override
    public void message() {
        // TODO Auto-generated method stub
        System.out.println("键盘发短信");
    }
}

  使用的时候就可以父类引用子类,注意这里父类不能引用自己

package com.chouxianglei;

public class initail {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Telephone telephone = new cellPhone();
        telephone.call();
        Telephone t2 = new smartPhone();
        t2.call();
        t2.message();
    }
}

 

18、关于接口

  有了抽象类的概念,就不得不提一下接口的概念。

  接口和抽象类类似,都是一种规范,但更加灵活,更加省事儿——比如有相同特征的,就可以针对相同特征设立接口,接口可以对接多个父接口,接口中都是abstract的,但不需要自己进行书写;

  所以举例子,PSP和智能手机都有玩游戏的特征,但智能手机继承自手机父类,PSP继承自游戏机父类,但共同的特征是一个接口

package com.chouxianglei;

public interface IPlayGame {
    public void playGame();
}

  注意:接口的命名一般以I开头,以和其他类进行区分;

package com.chouxianglei;

public class PSP implements IPlayGame {
    @Override
    public void playGame() {
        // TODO Auto-generated method stub
        System.out.println("PSP可以玩游戏");
    }
}

    有父类的一定写在接口前面

package com.chouxianglei;

public class smartPhone extends Telephone implements IPlayGame{

    @Override
    public void call() {
        // TODO Auto-generated method stub
        System.out.println("触摸屏打电话");
    }

    @Override
    public void message() {
        // TODO Auto-generated method stub
        System.out.println("触摸屏发短信");
    }
    
    public void playGame(){
        System.out.println("手机可以玩游戏");
    }
}

  引用中,接口还是看成是父类的,依然可以父类引用子类

package com.chouxianglei;

public class initail {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Telephone telephone = new cellPhone();
        telephone.call();
        Telephone t2 = new smartPhone();
        t2.call();
        t2.message();
        
        IPlayGame psp = new PSP();
        psp.playGame();
        IPlayGame s1 = new smartPhone();
        s1.playGame();
        
        //匿名内部类
        IPlayGame tt = new IPlayGame(){
            public void playGame(){
                System.out.println("匿名内部类使用");
            }            
        };
        tt.playGame();
        new IPlayGame(){
            public void playGame(){
                System.out.println("匿名内部类使用2");
            }
        }.playGame();
    }

}

  最后两段是匿名内部类,即在程序中直接进行定义的类,直接使用!

 19、关于UML

  初级的程序员能看懂这种设计类图形语言就行了!

  常见三种图:类图,用例图,序列图。

  TMUML还能直接生成语言,天。。。

  可以用visio画图http://blog.csdn.net/hyman_c/article/details/52586241