java面向对象学习日记01

1) 初识类与对象

介绍:类(一种自定义的数据类型)可以存放多个的属性(数据)和行为(类似c语言中的函数) 可以通过类创建多个对象(具体的实例 如:666是int的一个对象)
例:

public class oop {
        public static void main(String[] args) {
        student student1 = new student();//student1为对象名 student1所指的空间(数据)为对象
        student1.age=18;
        student1.name="小明";
        student1.gender="男";
        student student2 = new student();
        student2.age=19;
        student2.name="李明";
        student2.gender="女";
        System.out.println("1号学生信息"+student1.age+" "+student1.name+" "+student1.gender);
        System.out.println("2号学生信息"+student2.age+" "+student2.name+" "+student2.gender);

        }
}
class student //定义了一个学生'类'(自定义的数据类型)
{//属性/成员变量/field(如果不定义有默认值,规则和数组一致)
        int age;
        String name;
        String gender;
}

结果:

1号学生信息18 小明 男
2号学生信息19 李明 女

1.1) 对象分配机制

介绍:

  1. 栈:一般存放基本数据类型(局部变量)
  2. 堆:存放对象(student student1,数组等)
  3. 方法区:常量池(常量,比如字符串),类加载信息
    例:
public class oop {
        public static void main(String[] args) {
        student student1 = new student();
        //先在方法区加载student类属性信息和方法信息(属性和方法信息仅加载一次)
        //然后new student会在堆里开一个空间 空间内数值为默认值
        //student1 = new student()会使在栈里的student1指向刚刚在堆里的开的空间
        student1.age=18;//将堆里的默认值换成18
        student1.name="小明";//"小明"为字符串常量会被放在方法区常量池 堆里默认值会替换成常量池"小明"的地址
        student1.gender="男";//同上
        student student2 = student1;//把student1的地址复制给student2 student1和student2指向同一个空间
        System.out.println(student2.name);
        student1.name="李明";
        System.out.println(student2.name);
        }
}
class student //定义了一个学生'类'(自定义的数据类型)
{//属性/成员变量/field(如果不定义有默认值,规则和数组一致)
        int age;
        String name;
        String gender;
}

结果:

小明
李明

1.2) 成员方法

介绍:

  1. 一个方法最多有一个return
  2. 返回类型包括基本类型和引用类型,return值与返回类型要一致
  3. 如果方法是void,可以没有return语句,或只写return
  4. 方法定义时的参数称为形参;调用时用的参数称为实参
  5. 同一个类中的方法可以直接调用其它方法
  6. 不同类的方法需要调用要先在需要调用的类中创建被调用类
  7. 基本数据类型传递的是值,形参改变不影响实参
  8. 引用类型传递的是地址,可以通过形参影响实参
  9. 传入数据为类时,属性和方法的改变不会影响主栈
    例:
public class oop {
        public static void main(String[] args) {
                int answer,n=2,m=9,c;
                //方法类似于C语言的函数 不在主函数内调用 不会输出
                sum a1 =new sum();
                judge a2=new judge();
                a1.speak(n,m);//调用speak
                answer=a1.get(n,m);//将返回的值赋给answer
                System.out.println(answer);
                if(a2.get2(n,m)){System.out.println("为奇数");}
                else{System.out.println("为偶数");}
        }
}

class sum {       //public 表示方法是公开的
        //void 表示方法无返回值
        //speak 方法名
        //() 为形参列表
        //{}内为执行的代码
        public void speak(int n,int m) {
                System.out.println(n+"到"+m+"之和为");
        }

        //int 表示返回值为int类
        public int get(int n, int m) {
                int k=0;
                for(int p=n;p<=m;p++)
                {
                        k+=p;
                }
                return k;
        }
}
class judge
{
public boolean get2(int n,int m) {
        sum a = new sum();
        int k=a.get(n,m);
        return k%2!=0;
}
}

结果:

2到9之和为
44
为偶数

1.2.1) 方法递归调用

递归简介:同一个方法不断调用自己,每次调用传入不同变量,用来解决各种复杂问题(如汉诺塔)
例:

public class oop {
        public static void main(String[] args) {
        ta t=new ta();
        t.move(3,'a','b','c');
        }
}
class ta
{     public void move(int num,char a,char b,char c)
{
        if(num==1){System.out.println(a+"->"+c);}
        else{
                move(num-1,a,c,b); //将num-1个盘移到b柱上
                System.out.println(a+"->"+c);
                move(num-1,b,a,c);//将num-1个盘移到c柱上
        }

}

结果:

a->c
a->b
c->b
a->c
b->a
b->c
a->c

1.2.2) 方法重载

介绍:java允许同一类中,多个同名方法的存在,但要求形参列表不同(如System.out.println能输出不同数据类型)
例:

public class oop {
    public static void main(String[] args) {
    math math1=new math();
    System.out.println(math1.sum(4,5));
    System.out.println(math1.sum(4,7,9));
    }
}
class math
{
    public int sum (int n1,int n2)
    {
        return n1+n2;
    }
    public int sum (int n1,int n2,int n3)
    {
        return n1+n2+n3;
    }
}

结果:

9
20

1.2.3) 可变参数

简介:部分(数据类型相同但数量不同)方法重载的合并

  1. 一个形参列表中只出现一个可变参数
  2. 可变参数必须放在形参列表中的最后
  3. 可变参数的实参可以为多个或0个
    例:
public class oop {
    public static void main(String[] args) {
    math math1=new math();
    int n[]={1,3,5,7,10};
    System.out.println(math1.sum(2,3,5,7,11,13,17));
    System.out.println(math1.sum1(2,3,5,7,11,13,17));
    System.out.println(math1.sum(n));
    }
}
class math {
    public int sum(int... num) {
        int ans=0;
        for(int i=0;i<num.length;i++)
        {
            ans+=num[i];
        }
        return ans;
    }
    public int sum1(int c,int... num) {
        int ans=0;
        for(int i=0;i<num.length;i++)
        {
            ans+=num[i];
        }
        return ans;
    }
}

结果:

58
56
26

1.2.4) 作用域

简介:

  1. 属性在方法内都能使用,被称为全局变量
  2. 属性之外的其它变量,作用域为定义它的代码块中,被称为局部变量
  3. 全局变量有默认值,可以直接使用.局部变量没有默认值,不能直接使用
  4. 属性和局部变量可以重名,访问时遵循就近原则
  5. 同一个作用域中,比如同一个成员方法中局部变量不能重名
  6. 属性可以被其它类使用(通过对象调用),局部变量
  7. 属性可以加修饰符,局部变量不行
    例:
public class oop {
    public static void main(String[] args) {
    year nian=new year();
    nian.mouth();
    nian.week();
    }
}
class year
{
    int day=365;
    int c;
    public void mouth()
    {
        int day1=31;
        System.out.println(day);
        System.out.println(day1);
    }
    public void week()
    {
        System.out.println(day);
        System.out.println(c);
        //若在此处加上System.out.println(day1);的代码,程序报错
    }

}

结果:

365
31
365
0

1.2.5) 构造方法/构造器

简介:类的一种特殊方法,主要作用是完成对新对象的初始化

  1. 没有返回值
  2. 方法名和类名相同
  3. 参数列表和成员方法规则相同
  4. 构造器的调用由系统完成
  5. 一个类可以有多个构造器(即构造器的重载)
  6. 如果没有定义构造方法,系统会自动给类生成一个无参构造方法.一旦定义了新的构造器,系统的无参构造器就被覆盖,若想使用需重定义
    例:
public class oop {
    public static void main(String[] args) {
        year d1=new year(2,28);
        System.out.println(d1.mouth+" "+d1.day);
    }
}
class year
{   int mouth;
    int day;
    public year(int mouth1,int day1)
    {
        System.out.println("构造器被调用");
        mouth=mouth1;
        day=day1;
    }
}

1.3) this关键字

简介:

  1. this可以用来访问本类属性 方法 构造器
  2. this 用于区分当前类的属性和局部变量
  3. 访问成员方法的语法:this.方法名(参数列表)
  4. 访问构造器语法(只能在构造器中使用):this(参数列表)
  5. this不能在类定义外使用
    例:
public class oop {
    public static void main(String[] args) {
        person a1=new person();
        System.out.println(a1.age+" "+a1.height);
        a1.start(183,19);
        System.out.println(a1.age+" "+a1.height);
        a1.end();
        System.out.println(a1.age+" "+a1.height);

    }
}
class person {
    int height;
    int age;
    public person() {//访问构造器语句必须放在构造器中第一句
        this(180,18);//访问person(int height,int age)构造器
    }
    public person(int height,int age) {
        this.height = height;//前面有this就固定为属性,无则取就近原则
        this.age = age;
    }
    public void start(int height,int age) {
        System.out.println("调用start");
        this.height=height;
        this.age=age;
    }
    public void end() {
        this.start(0,0);//this.start()与start()类似但不同具体差别在继承体现
    }
}

结果:

18 180
调用start
19 183
调用start
0 0

2 包

简介:

  1. 包 能区分相同名字的类
  2. 当类很多时 包 能便于管理
  3. 包 能控制访问范围
  4. 包 的本质:创建不同的文件夹保存类文件
  5. 包的命名规则: 只能包含数字,字母,下划线,小圆点 但不能用数字开头 不能含关键字或保留字
  6. 包的命名规范: com.公司名.项目名.业务模块名
  7. package 是声明当前类所在的包,需要放在class的最上面,一个类中最多一个package
  8. import指令 位置放在package下面
    例:
package pet.num;
import pet.cat.black;//同名类只能引入一个 import pet.cat.black表示引入pet.cat包下black类
import pet.dog.*;//表示引入pet.dog 包下所有类
import java.util.Arrays;//java中自带的数组排序的类

public class num1 {
    public static void main(String[] args) {
        black shu=new black();
        pet.dog.black dog1=new pet.dog.black();//不引入包名需写全
        int []a={3,5,7,5,4,3,-1,11,7,13,0};
        Arrays.sort(a);
        for(int i=0;i<a.length;i++)
        {
            System.out.print(a[i]+" ");
        }
    }
}

结果:

-1 0 3 3 4 5 5 7 7 11 13 

3) 访问修饰符

简介:

  1. 公开级别: public 对外公开
  2. 受保护级别: protected 对子类和同一个包中的类公开
  3. 默认级别: 没有修饰符 向同一个包的类公开
  4. 私有级别: private 只有类本身可以访问,不对外公开
  5. 修饰符可以用来修饰类中的属性,成员方法及类
  6. 只有默认的和public才能修饰类
访问级别访问控制修饰符同类同包子类不同包
公开public
受保护protected×
默认没有修饰符××
私有private×××

4) 封装

简介:

  1. 封装就是把数据属性和数据的操作方法封装在一起,数据被保护在内部,程序其他部分只有通过被授权的操作方法,才能对数据进行操作
  2. 封装可以隐藏实现(方法)细节
  3. 封装可以对数据进行验证
  4. 封装的步骤:
  • 将属性进行私有化(private)
  • 提供一个公共的set方法,用于对属性判断并赋值
    public void setXxx(类型 参数名){
    //加入数据验证
    属性=参数名;
    }
  • 提供一个公共的get方法,用于获取属性的值
    public XX getXxx(){//权限判断
    return xx;
    }
    例:
package com.fezh;
public class enan {
    public static void main(String[] args) {
       person a1= new person();
       a1.setName("lihua");
       a1.setAge(23);
       a1.setSalary(3500);
       System.out.println(a1.info());
        System.out.println(a1.getSalary(1));
        person jack = new person("jack", 666, 5800);
        System.out.println(jack.info());
    }
}
class person{
    public person() {
    }
    public person(String name, int age, double salary) {
       setSalary(salary);//如果直接用this.name=name就会绕过set无法验证数据
       setAge(age);
       setName(name);
    }
    public String name;
    private int age;
    private double salary;
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
//set方法用来判断并对属性赋值
    public void setAge(int age) {
        if(age>=1&&age<=120){
        this.age = age;}
        else{
            System.out.println("年龄范围在1-120,超过范围取18");
            this.age=18;
        }
    }
    public void setName(String name) {
        if(name.length()>=2&&name.length()<=6){
        this.name = name;}
        else{
            System.out.println(("名字长度在2-6"));
            this.name="未登记";
        }
    }
    public double getSalary(int a) {
        if(a==123456)//给薪水查看上"密码"
        {return salary;}
        else {
            System.out.println("密码错误");
            return -1;
        }
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public String info(){
        return "name "+name+" age "+age+" 薪水 "+salary;
    }
}

结果:

name lihua age 23 薪水 3500.0
密码错误
-1.0
年龄范围在1-120,超过范围取18
name jack age 18 薪水 5800.0

5) 继承

简介:

  1. 基本语法:
    class 子类 extends 父类{
    }
  2. 子类自动拥有父类定义的属性和方法
  3. 父类又叫超类/基类 子类又叫派生类
  4. 子类要调用父类私有属性和方法,需要通过父类提供公共的方法去访问
  5. 子类必须调用父类的构造器(系统默认会用super语法调用父类的无参构造器 即super() )
  6. 若父类没有提供无参构造器,必须在子类的构造器中去指定使用父类哪个构造器完成对父类的初始化工作
  7. super() 与 this() 都只能放在构造器第一行 因此两方法不能共存于一个构造器
  8. java的所有类都是Object的子类
  9. 子类最多只能继承一个父类
继承
继承
继承
继承
D类 特有属性 特有方法
B类 共用属性 共用方法
A类 共用属性 共用方法
E类 特有属性 特有方法
C类 共用属性 共用方法

例:
父类:

package pet;
//dog和cat的父类
public class all {
    //共有属性
    public String name;
    public int age;
    private double sell;
    public void setScore(double sell) {
        this.sell = sell;}
        public void  info()
    {
            System.out.println("宠物名 "+name+" age "+age+" 价格 "+sell);
        }
    }

子类1:

package pet;
public class cat extends all {
    public void circus(){
        System.out.println("小猫"+name+"正在摸鱼");
    }
}

子类2:

package pet;
public class dog extends all {
    public void circus(){
        System.out.println("小狗"+name+"正在祈祷");
    }
}

测试:

package pet;
public class test {
    public static void main(String[] args) {
        dog dog1 = new dog();
        dog1.name="旺财";
        dog1.age=3;
        dog1.setScore(348);
        dog1.circus();
        dog1.info();
        System.out.println("--------");
        cat cat1 =new cat();
        cat1.name="大白";
        cat1.age=5;
        cat1.setScore(568);
        cat1.circus();
        cat1.info();
    }
}

结果:

小狗旺财正在祈祷
宠物名 旺财 age 3 价格 348.0
--------
小猫大白正在摸鱼
宠物名 大白 age 5 价格 568.0

6) supper关键字

简介:

  1. super代表父类的引用,用于访问父类(包括父类的父类的…直到object)的属性,方法,构造器 不能访问private属性/方法
  2. 使用super访问属性,方法时会跳过本类(用this访问时会优先访问本类,若本类没有再访问父类)
  3. 基本语法:
    访问父类属性:super.属性名
    访问父类方法super.方法名(参数列表)
    访问父类构造器:super(参数列表)

7) 方法重写/覆盖

简介:

  1. 子类的一个方法与父类某个方法的方法名称,参数一样,且子类方法的返回类型与父类方法返回类型一样或是其子类(如父类返回类型是Object 子类返回类型是String),我们就说这个子类的这个方法覆盖了父类的方法
  2. 子类方法不能缩小父类方法的访问权限(按照public>protected>默认>private的规则 子类只能扩大或相等 不能缩小)
    例:
    父类:
package fuf;
public class fufu {
    private String name;
    private int age;
    public fufu(String name,int age)
    {
        this.name =name;
        this.age=age;
    }
    public String talk()
    {
        return "my name is "+name+"今年"+age+"岁";
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

子类:

package fuf;
public class son1 extends fufu{
    private int id;
    private double score;
    public son1(String name, int age, int id, double score) {
        super(name, age);//访问父类构造器
        this.id = id;
        this.score = score;
    }
    public String talk(){
        return super.talk()+" id="+id+" score="+score;
    }//对父类talk方法的重写
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
}

主类:

package fuf;
public class mainn {
    public static void main(String[] args) {
        fufu Lihua=new fufu("Lihua",10);
        System.out.println(Lihua.talk());
        son1 xiaoming = new son1("xiaoming", 20, 12138, 61);
        System.out.println(xiaoming.talk());
    }
}

结果:

my name is Lihua今年10岁
my name is xiaoming今年20岁 id=12138 score=61.0

8) 多态

8.1) 初识多态

多态的体现:

  1. 方法的多态:
    重写和重载体现多态
  2. 对象的多态
  • 一个对象的编译类型(定义时 = 号左边)和运行类型(定义时 = 号右边)可以不一致
  • 编译类型在定义对象时,就确定了,不能改变
  • 运行类型可以改变
    多态的向上转型
  1. 本质:父类的引用指向了子类对象
  2. 语法: 父类类型 引用名=new 子类类型
  3. 注意事项:
  • 可以调用父类中所有成员
  • 不能调用子类中特有成员(即没有重写父类方法的子类方法)
    多态的向下转型
  1. 语法: 子类类型 引用名=(子类类型)父类对象
  2. 只能强制转移父类的引用,不能强制转移父类类型
  3. 父类的引用必须指向当前目标类型的对象
  4. 向下转型后可以调用子类类型中所有成员
    例:
package 多态;
public class justdo {
    public static void main(String[] args) {//sun和moon都为god的子类且praise重构
        god god1 =new god();
        god1.praise();
        god1 =new moon();// god 为 god1 的编译类型 moon 为 god1 的运行类型
        god1.praise();
        god1 =new sun();//运行类型变更为 sun
        god1.praise();
        god god0=god1;//向上转型
        //sun和moon含独有方法eng不能直接引用
        god god2 =new moon();
        moon god3 =(moon) god2;//只能强制转移父类的引用,不能强制转移父类类型
        god3.eng();//向下转型后即可调用子类独有方法
        sun god4 =(sun) god1;//父类的引用必须指向当前目标类型的对象 例如要god4转型成sun god1的运行类型要是sun
        god4.eng();//属性看编译类型 不看运行类型
        System.out.println(god1 instanceof god);//引用名a instanceof 类型b 可以判断是否为a是否为b类型或为b类型的子类
        System.out.println(god1 instanceof sun);
        System.out.println(god1 instanceof moon);
    }
}

结果:

赞美神!
赞美月亮!
赞美太阳!
moon!
sun!
true
true
false

8.2) 动态绑定机制

  1. 当调用对象方法时,该方法会和该对象的内存地址(即运行类型)绑定
  2. 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用
    例:
package fuf;
public class mainn {
    public static void main(String[] args) {
     class xm
     {
         public int sc=60;
         public int getSc() {
             return sc;
         }
         public int up()
         {
             return getSc()+10;
         }
         public int down()
         {
             return sc-10;
         }
     }
        class lihua extends xm
        {
            public int sc=59;
            public int getSc() {
                return sc;
            }
            //public int up()
            //{
            //    return getSc()+10;
            //}
            //public int down()
            //{
            //    return sc-10;
            //}
        }
        xm stu=new lihua();
        System.out.println(stu.up());//遵循动态绑定机制调用lihua.getSc
        System.out.println(stu.down());//直接引用xm的sc
    }
}

结果

69
50

8.3) 多态数组

简介:数组的定义类型为父类类型,里面保存的元素类型为子类类型
语法:父类类型[] 引用名=new 父类类型[i] (i为数组长度)
调出子类特有方法:((子类类型)引用名[i]).方法名()
(即向下转型 可以用instanceof判断是否为对应子类以防报错)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值