zoukankan      html  css  js  c++  java
  • java----面对对象

    对象被创建的步骤

    1.分配对象空间,并将对象成员变量初始化为0或空

    2.执行属性值的显式初始化

    3.执行构造方法(此时的对象已经被创建,我们可以在这一步对对象进行进一步的初始化工作)

    4.返回对象的地址给相关的变量

     面对对象:

    public class Demo {
    	public static void main(String[] args){
    		Horse h = null;
    		h = new Horse();
    //		h.name = "dd";
    		h.eat();
    		h = null; //释放对象
    	}
    }
    
    class Horse{
    	String name;
    	public void eat(){
    		System.out.println(name);
    	}
    	
    }
    

      

     封装性:

    public class Demo {
    	public static void main(String[] args){
    		Horse h1 = new Horse();
    //		h1.name = "小明";//由于 name设置了私有字段,此时在给对象赋值,会报错;
    		h1.setName("小明");
    		System.out.println(h1.getName());
    }
    }
    class Horse{
    	//属性的封装
    	private String name;
    	private int age;     //成员变量,在类中定义,在堆内存,对象清空,则成员变量清空,有默认初始值,像String引用变量初始值为null,int的初始值为0;
    	public void setName(String name){ //参数也是局部变量
    		int a = 111; //局部变量;在方法中定义,在栈内存,方法调用完毕,就清空,没有初始值,必须定义,赋值后,才能调用。
    		this.name = name;
    	}
    	public String getName(){
    //		return name;
    		return this.name;  // 可以使用this调用其他方法和属性,this可以省略,this前面可以加上类名  Horse.this.name();
    	}
    }
    

      

     构造方法和构造方法的重载:

    类似python中的__init__(self){}

    public class Demo {
    	public static void main(String[] args){
    		Horse h = new Horse();
    		Horse h2 = new Horse(1);
    	}
    }
    class Horse{
    	public Horse(){ //方法名称和类名相同,没有返回值
    		System.out.println("我是构造方法");
    	}
    	public Horse(int a){
    		System.out.println("a="+a);
    	}
    }
    

    构造方法之间的调用,用this()

    public class Demo {
    	public static void main(String[] args){
    		Horse h2 = new Horse(1);
    	}
    }
    class Horse{
         public Horse(){  //默认构造方法,可以保留
          
        }
    	public Horse(String b){ //方法名称和类名相同,没有返回值
    		System.out.println(b);
    	}
    	public Horse(int a){
    		this("11");  //调用另一个构造方法,注意,这条语句,只能放在最前面,否则报错;,限制了,不能调用多个;
              this("22");  //报错,只能调用一个
    		System.out.println("a="+a);
    	}
    }
    

     对象之间的关联:

    public class Demo {
        public static void main(String[] args){
        	Hero hero1 = new Hero("刘备");
        	Weapon weapon1 = new Weapon("双股剑");
        	
        	hero1.setWeapon(weapon1);//将对象传递给一个对象,实现对象之间的关联
        	
        	System.out.println(hero1.getWeapon().getName());
        	
    } 
    }
    class Hero{
        //属性的封装
    	private String name;
    	private Weapon weapon;
    	
    	public Hero(String name){
    		this.name = name;
    	}
        
        public void setWeapon(Weapon weapon){
        	this.weapon = weapon;
        }
        public Weapon getWeapon(){
        	return this.weapon;
        }
    }
    class Weapon{
    	private Hero hero;
    	private String name;
    	public Weapon(String name){
    		this.name = name;
    	}
    	public void setHero(Hero hero){
    		this.hero = hero;
    	}
    	public String getName(){
    		return this.name;
    	}
    }
    

      

     继承:

    方法的重载:发生在同一个类中,函数名相同,参数列表不相同,与返回值返回值(类型)无关;

    方法的重写:发生在继承的关系中,函数名相同,参数列表相同,返回值(类型)需要相同。子类的访问修饰符需要大于或者等于父类的访问修饰符,子类的异常声明要小于或等于父类的异常声明,如果方法被private 、static修饰,那么方法不能被继承/重写。 final修饰,只能继承,不能重写

    public class Demo {
        public static void main(String[] args){
        	Dog dog = new Dog();    //子类创建对象时 ,也会 自动 调用父类的默认的构造方法
        	System.out.println(dog.name);
        	dog.print();
        }
    }
    
    class Animal{
    	protected String name = "动物";
    	public Animal(){
    		System.out.println("我是Animil 默认构造方法");
    	}
    	public Animal(String name){
    		System.out.print("我是Animial  传参构造方法");
    	}
    	public void print(){
    		System.out.println("Animal");
    	}
    }
    class Dog extends Animal{   //继承的写法
    	public Dog(){
    		super("传值");       //如果有super,就会继承super所指的构造方法,具体执行那一个,看传参的列表
    //		super();            //如果没有传值,就会执行父类的默认的构造方法,前提父类必须保留默认的构造方法;
    							//注意1:默认情况下,会自动添加super(),如果自己写了super,就会覆盖默认的
    							//注意2:super(),只能方法最开始的位置
    	}
    	public void print(){
    		super.print();     //继承父类的方法;
    		System.out.println("Dog");
    	}
    }

     抽象类:

    1、抽象类可以没有抽象方法,有抽象方法的一定是抽象类

    2、非抽象类继承抽象类必须实现所有的抽象方法

    3、抽象类可以继承抽象类,可以不实现父类的抽象方法

    4、抽象类可以有方法实现和属性

    5、抽象类不能被实例化

    6、抽象类不能声明final

    7、抽象类可以有构造方法

    public class Demo {
        public static void main(String[] args){
        	Dog dog = new Dog();
        }
    }
    
    abstract class Animal{    //声明该类是一个抽象类,只能继承,不能实例化
    	{
    		System.out.println("可以有构造方法");
    	}
    	public abstract void eat();  //可以没有抽象方法  ,如果有了抽象方法,该类必须是抽象类,并且该抽象方法必须子类实现;
    	public void run(){           //普通的方法可以不用被实现
    		System.out.print("我可以跑");
    	}
    }
    
    class Dog extends Animal{
    	public void eat(){
    		
    	}
    }
    

      

     接口:

    1、抽象类实现接口,可以不实现接口的方法,非抽象类,必须实现接口的所有的方法;

    2、接口的方法没有声明访问修饰符,默认为public

    3、接口不能有构造方法,接口不能被实例化

    4、接口之间的继承用extends ,定义接口用interface ,类实现接口用implements

    5、接口只能定义常量,抽象方法,(jdk1.8之后有默认的实现方法,和静态方法)

    6、final不可以修饰接口

    public class Demo {
        public static void main(String[] args){
        	Person person = new Person();
        	person.print();  //默认的方法实现;
        }
    }
    
    interface IEat{
    //	public abstract void eat();
    	void eat();  //简写,定义抽象方法
    	
    //	public final static int NUM = 10;
    	int NUM = 10; //简写,定义常量
    	
    	public default void print(){
    		System.out.println("默认方法实现");  //jdk1.8之后有 默认方法实现(加上default),不能有其他的方法实现
    	}	
    }
    interface ISleep{
    	void sleep();
    }
    interface IRun extends IEat,ISleep{   //接口可以有多继承
    	void run();
    }
    
    class Person implements IRun,ISleep{  //接口的实现,类可以继承多个接口(不是接口的继承)
    	public void sleep(){}             //必须实现接口的所有的方法
    	public void run(){}
    	public void eat(){}
    	
    }
    

      

     多态:  

    public class Demo {
        public static void main(String[] args){    	
        	Chick smailchick = new SmailChick();  //用父类的引用指向子类对象,(用大的类型接受小的类型,向上转型,自动转换)
        	eat(smailchick);
        	
        	SmailChick smailchick2 = new SmailChick();
        	eat(smailchick2);
        	
        	Chick bigchick = new BigChick();
        	eat(bigchick);
        }
        public static void eat(Chick c){  //多态性,Chick可以接受比他小的或者等于他的类型,(例如int可以接受short类型)
        	c.eat();
    //    	c.song();  //直接写会报错,原因Chick中没有song方法,在运行的时候,c才是所new的对象,在编译的时候c还是chick
        	
        	if(c instanceof BigChick){              //在转换之前做类型的判断
    //    		BigChick bigchick = (BigChick)(c);  //若果父类中没有定义song()方法,就需要   强制转换  将Chick转变成BigChick
    //    		bigchick.song();
        		((BigChick)c).song();               //简写
        	}
        }
    }
    
    abstract class Chick{
    	public abstract void eat();
    }
    class SmailChick extends Chick{
    	public SmailChick(){
    		super();
    	}//默认自动添加
    	public void eat(){
    		System.out.println("我是小鸡,我爱吃米");
    	}
    }
    
    class BigChick extends Chick{
    	public void eat(){
    		System.out.println("我是大鸡,我爱吃虫");
    	}
    	public void song(){
    		System.out.println("我是大鸡,我会唱歌");
    	}
    }

    this的本质 

    指明当前的对象,不能放到static静态方法中

    class Test{
        int a;
        public Test(int a){
            //给成员变量进行赋值
            this.a = a;
        }
        public Test(){
            //调用另一个构造方法,只能放在代码的第一行(所以只能有一个)
            this(1);
        }
    }

    java中的new到底为我们做了什么?

        参考https://www.cnblogs.com/KingIceMou/p/7245446.html

    String 中的hashcode()和equals()?

    hashcode和equals都是为了对比两个对象是否相等一致,那么为什么会有两个呢?

      hashcode()的判断是比较高效的,如果hashcode不一样那么这两个对象一定不相等。但是hashcode相等不能代表这两个对象一定相等,需要equals进行复杂的逻辑判断最终确定是否相等。所有我们在equals判断之前先判断hashcode是否相等可以一定程度提高效率,之后hashcode为了false,就可以不需要在判断equals了。

      hashcode目的只是让一个对象只存在唯一的hashcode值,但是一个hashcode值可能会被多个对象共享。所以只要两个对象的hashcode值不相等,那他们对象肯定是不相等的。

      这种大量的并且快速的对象对比一般使用的hash容器中,比如hashset,hashmap,hashtable等等,比如hashset里要求对象不能重复,则他内部必然要对添加进去的每个对象进行对比,而他的对比规则就是像上面说的那样,先hashCode(),如果hashCode()相同,再用equal()验证,如果hashCode()都不同,则肯定不同,这样对比的效率就很高了。

    我们再来看看String中的hashcode和equals?

      String重写了objdect中的hashcode()和equals()方法,所以这两个方法都可以用来判断字符串是否相等。只需要使用任意一个就可以判断?

      new Object().equals(objdect)所有的类中默认的equals方法都是和"=="一样的效果,判断内存地址是否一样,只是String重写了equals。

        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    
        public static void main(String[] args) {
            StringBuilder stringBuilder = new StringBuilder("11");
            System.out.println(stringBuilder.hashCode());
            stringBuilder.append("1");    
            //比较的是内存地址 
            System.out.println(stringBuilder.hashCode());
    
            String a = "a";
            String b = "a";
            System.out.println(a.hashCode()+"=="+b.hashCode()
    );
       
    

      

    补充

    访问修饰符

     

     

      

      

  • 相关阅读:
    SPI传输协议笔记
    Linux power supply class
    linux ramdisk 参数问题
    Android事件处理过程分析
    PWM 参数计算
    6.828 lab3
    6.828 lab1
    i.MX53 上电启动过程
    linux jiffies的比较
    在arm板上安装Debian
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/10656832.html
Copyright © 2011-2022 走看看