Java面向对象

Posted careyzhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面向对象相关的知识,希望对你有一定的参考价值。

source:http://blog.java1234.com/index.html?typeId=1

Java面向对象三大特性;

封装:类,类里有方法,属性,可以封装很多功能 仅仅对外暴露一些接口,来实现模块化,组建化,和安全性;

继承:Java中的类可以继承,类似子女可以继承父母的东西;来实现可扩展;

多态:Java中的父类接口可以指向子类实现的引用;

类与对象的关系

通俗的举个例子,比如人类是一种类,张三这个人就是人类的具体的一个个体,也就是java中的对象;这就是一个类与对象的关系;

//新建一个Person类,java文件名和类名必须一致
public class Person {
 
    String name; // 在类中,定义一个姓名name字符串属性 可以存在字符串 类似"张三"
    int age; // 在类中,定义一个年龄age属性
     
    /**
     * 定义一个方法  public表示共有 权限最大  void表示返回值是空  speak是方法名 括号里可以加参数
     */
    public void speak(){
        System.out.println("我叫"+name+" 我今年"+age);
    }
     
    public static void main(String[] args) {
        // 定义一个Person类的对象zhangsan
        Person zhangsan;
        // 实例化对象
        zhangsan=new Person();
        // 给对象的name属性赋值
        zhangsan.name="张三";
        // 给对象的age属性赋值
        zhangsan.age=23;
        zhangsan.speak(); // 调用对象的方法
    }
}

内存分析

技术分享图片

方法是对象的一部分,也称为行为。

public class Person {
 
    int speak(String name,int age,String ...hobbies){
        System.out.println("我叫"+name+",我今年"+age+"岁了");
        for(String hobby:hobbies){
            System.out.println(hobby+" ");
        }
        // 获取爱好的长度
        int totalHobbies=hobbies.length;
        return totalHobbies;
    }
     
    public static void main(String[] args) {
        Person person=new Person();
        int n=person.speak("张三",23,"游泳","唱歌");
        System.out.println("有"+n+"个爱好");
    }
}

方法的值传递:

值传递 在方法里改变变量的值 作用范围仅仅是方法里 对外面不影响;

引用传递,传递的是地址,对象里的属性在方法里值修改,对外面有影响,我们通过对象.属性可以获取到最新的数据;

class SanWei{
    int b; // 胸围
    int w; // 腰围
    int h; // 腿围
}
 
public class Person {
 
    void speak(int age,SanWei sanWei){
        System.out.println("我今年"+age+"岁了,我的三围是:"+sanWei.b+","+sanWei.w+","+sanWei.h);
        age=24; // 作用范围是方法里
        sanWei.b=80; // 胸围改成80
    }
     
    public static void main(String[] args) {
        Person xiaoli=new Person();
        int age=23;
        SanWei sanWei=new SanWei();
        sanWei.b=90;
        sanWei.w=60;
        sanWei.h=90;
        // age传递的是值 ,sanWei是对象,传递的是引用(地址,c里叫指针)
        xiaoli.speak(age,sanWei);
        System.out.println(age);  
        System.out.println(sanWei.b);
    }
}

内存示意图

技术分享图片

方法的重载:类里面有两个或者多个重名的方法,但是方法的参数个数、类型、顺序至少有一个不一样,这时候局构成方法重载;

public class Demo01 {
 
    int add(int a,int b){
        System.out.println("方法一");
        return a+b;
    }
     
    /**
     * 方法的重载,参数个数不一样
     * @param a
     * @param b
     * @param c
     * @return
     */
    int add(int a,int b,int c){
        System.out.println("方法二");
        return a+b+c;
    }
     
    /**
     * 方法的重载,参数的类型不一样
     * @param a
     * @param b
     * @return
     */
    int add(int a,String b){
        System.out.println("方法三");
        return a+Integer.parseInt(b);
    }
     
    /**
     * 参数类型个数一样,返回值类型不一样 不算重载,直接会报错,说方法重名
     * @param args
     */
    /*long add(int a,int b){
        return a+b;
    }*/
     
    public static void main(String[] args) {
        Demo01 demo=new Demo01();
        System.out.println(demo.add(1, 2));
        System.out.println(demo.add(1, 2,3));
        System.out.println(demo.add(1, "3"));
    }
}

注意:假如参数个数和类型一样,返回值不一样,不能算重载,直接是编译出错,编译器认为是方法重复了。

java里方法分为 static静态方法和普通方法

所谓静态方法 是加了static修饰词的方法,我们使用的时候 一般用类名.方法 方式调用;

当然也可以用对象.方法 调用; 一般java里的工具类里的工具方法 用static修饰,作为静态方法;

 

递归,就是程序调用自身,我们讲的是方法递归调用,也就是在方法里自己调用自己;

//求阶乘  1*2*3*...*(n-1)*n 
public class Demo {
 
    /**
     * 递归方式
     * @param n
     * @return
     */
    static long diGui(int n){
        if(n==1){
            return 1;
        }
        return diGui(n-1)*n;
    }
     
    public static void main(String[] args) {
        System.out.println(Demo03.diGui(5));
    }
}
/*用递归实现斐波那契数列 1、1、2、3、5、8、13、21、...

   F(1)=1, f(2)=1

   F(N)=F(N-1)+F(N-2)
*/
public class Demo{
 
    long fun(int n){
        if(n==1 || n==2){
            return 1;
        }
        return fun(n-1)+fun(n-2);
    }
     
    public static void main(String[] args) {
        System.out.println(new Test().fun(7));
    }
}

构造方法

概念:构造方法是一个特殊的方法,这个特殊方法用于创建实例时执行初始化操作;

特点 1,没有返回值类型,区别于其他一般方法;

        2,方法名和类名一样;

注意点:

1,假如没有构造方法,系统会自动生成一个默认的无参构造方法;

2,假如有构造方法,系统不会自动生成构造方法;

/**
 * 定义人类
 * @author user
 *
 */
public class People {
 
    // 定义属性 
    private String name; // 实例化对象时,默认值是null
    private int age; // 实例化对象时,默认值是0
     
    /**
     * 默认构造方法
     */
    People(){
        System.out.println("默认构造方法!");
    }
     
    /**
     * 有参数的构造方法
     * @param name2
     * @param age2
     */
    People(String name2,int age2){
        System.out.println("调用的是有参数的构造方法");
        name=name2;
        age=age2;
    }
     
    public void say(){
        System.out.println("我叫:"+name+",我今年:"+age);
    }
     
    public static void main(String[] args) {
        // People people=new People();
        People people=new People("张三",20);
        people.say();
    }
}

 

this,关键字,表示当前对象

1,使用this调用本类中的属性;

2,使用this调用构造方法;

/**
 * 定义人类
 * @author user
 *
 */
public class People {
 
    // 定义属性 
    private String name; // 实例化对象时,默认值是null
    private int age; // 实例化对象时,默认值是0
     
    /**
     * 默认构造方法
     */
    People(){
        System.out.println("默认构造方法!");
    }
     
    /**
     * 有参数的构造方法
     * @param name
     * @param age
     */
    People(String name,int age){
        this(); // 调用无参数的构造方法
        System.out.println("调用的是有参数的构造方法");
        this.name=name;
        this.age=age;
    }
     
    public void say(){
        System.out.println("我叫:"+name+",我今年:"+age);
    }
     
    public static void main(String[] args) {
        // People people=new People();
        People people=new People("张三",20);
        people.say();
    }
}

运行输出:

默认构造方法!
调用的是有参数的构造方法
我叫:张三,我今年:20

 

 访问控制权限:private(私有), package(包访问权限),protected(子类访问权限),public(公共访问权限)

 

代码块主要就是通过{}花括号 括起来的代码;

主要分为 普通代码块 构造块 静态代码块三类。

普通代码块:仅仅是花括号括起来的代码块;

构造块作用就是扩展构造器功能 每次实例化对象都会执行构造块里的内容,每次调用构造方法 都会先执行 构造块;

静态代码块:{}花括号前加static修饰词 在类加载的时候执行 而且只执行一次;

 

String类

实例化String对象

public static void main(String[] args) {
        // 实例化String的方式一
        String name1="张三";
        System.out.println("name1="+name1);
         
        // 实例化String的方式二
        String name2=new String("李四");
        System.out.println("name2="+name2);
}

“==”VS“equals方法”

“==” 比较的是引用(是否指向同一个内存块)  “equals”比较的是具体内容;

public static void main(String[] args) {
        String name1="张三";  // 直接赋值方式
        String name2=new String("张三"); // new方式
        String name3=name2; // 传递引用
         
        // ==比较的是引用
        System.out.println("name1==name2:"+(name1==name2));
        System.out.println("name1==name3:"+(name1==name3));
        System.out.println("name2==name3:"+(name2==name3));
         
        // equals比较的是具体内容
        System.out.println("name1.equals(name2):"+(name1.equals(name2)));
        System.out.println("name1.equals(name3:"+(name1.equals(name3)));
        System.out.println("name2.equals(name3):"+(name2.equals(name3)));
}

运行输出:

name1==name2:false

name1==name3:false

name2==name3:true

name1.equals(name2):true

name1.equals(name3:true

name2.equals(name3):true

技术分享图片

String两种实例化方式的区别:

直接赋值方式,创建的对象存放到字符串对象池里,假如存在的,就不会再创建;

new对象方式,每次都创建一个新的对象;

public static void main(String[] args) {
        String name1="张三";
        String name2="张三";
        String name3=new String("张三");
        String name4=new String("张三");
         
        System.out.println("name1==name2:"+(name1==name2));
        System.out.println("name1==name3:"+(name1==name3));
        System.out.println("name3==name4:"+(name3==name4));
}

运行输出:

name1==name2:true

name1==name3:false

name3==name4:false

技术分享图片

字符串的内容不可变性

字符串的特性:不能改变字符串的内容;

要想改变,只能通过指向一个新的内存地址;

public static void main(String[] args) {
        String name="张";
        name+="三";
        System.out.println(name);
}

技术分享图片

String类的常用方法:

 1、char chartAt(int index) 返回指定索引处的char值,这里的index 是从0开始的

public static void main(String[] args) {
        String name="张三";
        char ming=name.charAt(1);
        System.out.println(ming);
         
        String str="我是中国人";
        for(int i=0;i<str.length();i++){
            System.out.println(str.charAt(i));
        }
}

运行输出:

2、int length() 返回字符串的长度

3、int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。

public static void main(String[] args) {
        // indexOf方法使用实例
        String str="abcdefghijdklmoqprstuds";
        System.out.println("d在字符串str中第一次出现的索引位置:"+str.indexOf(‘d‘));
        System.out.println("d在字符串str中第一次出现的索引位置,从索引4位置开始:"+str.indexOf(‘d‘,4));
}

4、String substring(int beginIndex)   返回一个新的字符串,它是此字符串的一个子字符串。

public static void main(String[] args) {
        // substring方式读取
        String str="不开心每一天";
        String str2="不开心每一天,不可能";
        String newStr=str.substring(1);
        System.out.println(newStr);
        String newStr2=str2.substring(1, 6);
        System.out.println(newStr2);
}

5、public String toUpperCase()  String 中的所有字符都转换为大写

public static void main(String[] args) {
        String str="I‘m a boy!";
        String upStr=str.toUpperCase(); // 转成大写
        System.out.println(upStr);
        String lowerStr=upStr.toLowerCase(); // 转成小写
        System.out.println(lowerStr);
}

String类综合案例

//“ aB232 23 &*( s2 ”指定字符串,要求去掉前后空格,然后分别统计其中英文字符,空格,数字和其他字符的个数;
public static void main(String[] args) {
        String str=" aB232 23 &*( s2 ";
        String newStr=str.trim(); // 去掉前后空格
        System.out.println("str="+str);
        System.out.println("newStr="+newStr);
         
        int yingWen=0; // 英文个数
        int kongGe=0; // 空格个数
        int shuZi=0; // 数字个数
        int qiTa=0; // 其他
         
        for(int i=0;i<newStr.length();i++){
            char c=newStr.charAt(i);
            // 判断英文字符
            if((c>=‘a‘&&c<=‘z‘)||(c>=‘A‘&&c<=‘Z‘)){
                yingWen++;
                System.out.println("英文字符:"+c);
            }else if(c>=‘0‘&&c<=‘9‘){
                shuZi++;
                System.out.println("数字字符:"+c);
            }else if(c==‘ ‘){
                kongGe++;
                System.out.println("空格字符:"+c);
            }else{
                qiTa++;
                System.out.println("其他字符:"+c);
            }
        }
         
        System.out.println("英文个数:"+yingWen);
        System.out.println("空格个数:"+kongGe);
        System.out.println("数字个数:"+shuZi);
        System.out.println("其他个数:"+qiTa);
}
//字符串反转,“abcdefg”,通过编程得到一个新的字符串“gfedcba”
public static void main(String[] args) {
        String str="abcdefg";
        String newStr="";
        for(int i=str.length()-1;i>=0;i--){
            newStr+=str.charAt(i);
        }
        System.out.println(newStr);
}
//将字符串“1,3,5,7,9”,转换成数组,数组元素是整数元素1,3,5,7,9 ,
注意:这里需要使用int的包装类的parseInt方法 把字符串转成int类型;
public static void main(String[] args) { String str="1,3,5,7,9"; int shuZi=0; for(int i=0;i<str.length();i++){ if(str.charAt(i)!=‘,‘){ shuZi++; } } int []arr=new int[shuZi]; int j=0; for(int i=0;i<str.length();i++){ if(str.charAt(i)!=‘,‘){ arr[j]=Integer.parseInt(str.charAt(i)+""); j++; } } for(int a:arr){ System.out.print(a+" "); } }

以上是关于Java面向对象的主要内容,如果未能解决你的问题,请参考以下文章

Java中面向对象的三大特性之封装

JAVA方法的定义

java 为啥要实现 function?

Java 封装

Java 封装

Java 封装