java丨【第三、四章】面对对象编程技术

类定义

 类是模板、是对象共同特征的抽取,对象是类的具体化、实例化。

1.

pulic class 类名
{
数据成员
pulic 方法成员(类名 参数)
{

}


2.public  类名(数据成员)//构造器,返回值什么都不能写,void也不能写
}


准则:任何类必须要有至少一个构造器,以实现空间初始化。
如果一个类没有定义任何构造器,则编译器自动帮你生成一个(称为默认或无参构造器)。
 

新建

例:求两点间距离。

public class Point{
   protected int x;
   protected int y;
   public getDistance(Point p){
      return Math.sqrt((this.x - p.x)*(this.x - p.x)
             +(this.y - p.y)*(this.y - p.y)
             );
   }
   public  Point(int x,int y){//当实例变量和方法参数名称相同时,使用 “this” 关键字来引用实例变量。在构造函数中,使用 “this” 关键字调用其他构造函数,但必须是在构造方法的第一行出现

      this.x=x;
      this.y=y;
   }
}

(可以添加后面提到的默认构造器的重载)

调用:
public static void main(String[] args){
  Point p1,p2;
  p1=new  Point(1,2);
  p2=new  Point(2,3);
  double d=p1.getDistance(p2);//p1就是隐蔽的this
  System.out.println("distance="+d);
}

成员变量

成员方法


(常考)static静态的-类的数据成员
1)数量:一个类中只有一份
2)生命期:类加载到内存中,诞生;从内存中移除,死亡。
3)调用格式:类名.成员名 如Point.w

vs     对象的数据成员
1)数量:每一个对象,都包含对象的数据成员,有多少个对象就有多少份数据成员
2)生命期:创建对象时,诞生;对象空间回收时,死亡。
3)调用格式:对象引用.数据成员 如p1.x


在对象的方法成员中包含this,类的数据成员和对象的数据成员都可以直接用。

在类的方法成员中没有this,可以直接使用类的数据成员,但只能间接调用对象成员。
 

四种修饰符

  • public表示该属性或方法可以被任何其他类访问;
  • private表示只有类自身的方法可以访问该属性或方法
  • protected表示该属性或方法可以被同一个包内的类和不同包中的子类访问
  • 默认表示该属性或方法可以被同一个包内的类访问。

数据成员尽可能地隐藏,方法成员尽可能地公开。

main方法

重写和重载

          重载是在同一个类中定义多个方法,方法名相同但参数列表(类型或次序或个数)不同,目的是提供不同的方法重载形式;一个方法在所在的类中可以被重载多次

       

  构造方法能被重载,但不能被重写。

构造器的重载:
 public  Point(int x){
      this(x,0);
 }
 public  Point(){
      this(0);//this(0,0);
 }
这就是默认构造器,最好也写一下。

参数构造器

public class ColorPoint extends Point{
    protected int c;
    public ColorPoint(int x,int y,int c){
    	super(x,y);//调用父类的两个参数的构造器
    	this.c=c;    	
    }
    public ColorPoint(int x,int y){
    	this(x,y,0);   	
    }
    public ColorPoint(){
    	this(0,0);   	
    }
}


    例:读重载相关程序写出打印结果

根据数据类型
1.int
2.double:3L是long型,这里会自动类型转换,根据(byte-char/short-int-long-float-double)不断向上找到数据类型为double
3.int
4.int[]
5.int[]:更特殊的数据类型优先,因为int []是一个Object但Object不一定是int[],也就是说int[]范围更窄更特殊


    而重写是子类对父类方法的重新实现,目的是改变方法的行为。
    必须是非静态static成员的对象方法
    必须方法名、参数相同,返回值类型相容
    必须能够被子类继承(也就是说能从子类中访问出来)

例:读重写相关程序写结果
public class TA{
    protected int x=1;
    public void f(){System.out.println("TA-f()");}
    public static void g(){System.out.println("TA-g()");} 
}

public class TB extends TA{
    protected int x=2;
    public void f(){System.out.println("TB-f()");}
    public static void g(){System.out.println("TB-g()");}
}

问在main中执行以下代码,表示结果:
代码1:
TB t=new TB;//前一个TB是定义时的类型,后一个是运行时的类型
System.out.println(t.x);//2
t.f();//TB-f()
t.g();//TB-g()
TB.g();//TB-g()

代码2:
TA t=new TB;//TA是定义时的类型同时也是父,TB是运行时的运行同时也是子(重点理解)
System.out.println(t.x);//1,访问的是定义的类型,也就是父亲TA
t.f();//TB-f(),因为是f()方法重写,访问的是运行时的类型,也就是儿子TB,牢记原则:子对象代替父对象使用!
t.g();//TA-g(),因为static类方法没有重写只有隐藏,这里显示定义时的类型
TA.g();//TA-g()

例:对比重载重写,读程序写结果

class Shape {
    public void draw() {
        System.out.println("Drawing a shape");
    }
    public void draw(String color) {
        System.out.println("Drawing a shape with color: " + color);
    }
}//重载

class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}//重写

public class OverloadingVsOverriding {
    public static void main(String[] args) {
        Shape shape = new Shape();
        shape.draw();               // Output: Drawing a shape
        shape.draw("red");          // Output: Drawing a shape with color: red

        Circle circle = new Circle();
        circle.draw();              // Output: Drawing a circle

        //展示了多态的概念,其中运行时决定调用的是子类的方法。
        Shape shapeCircle = new Circle();
        shapeCircle.draw();         // Output: Drawing a circle
        shapeCircle.draw("blue");   // Output: Drawing a shape with color: blue
    }
}

抽象类和接口

       只声明而没有实现的方法称为抽象方法,抽象方法必须使用abstract关键字来修饰,用abstract修饰的类称为抽象类,抽象类的子类必须实现父类的所有抽象方法后才能实例化,否则这个子类也成为一个抽象类。

      如果一个抽象类中的所有方法都是抽象的,即接口。接口是由常量和抽象方法组成的特殊类,是对抽象类的进一步抽象。接口可以继承其他的接口,并添加新的属性和抽象方法。

1.实现方法:

(1)抽象类中不是所有的方法都是抽象方法,可以在抽象类中声明并实现方法,也可以有被abstract修饰的方法(抽象方法),因为存在抽象方法,所以该类必须是抽象类。

(2)接口要求只能包含抽象方法,抽象方法是指没有实现的方法。接口就根本不能存在方法的实现。

2.子类使用的关键词不一样:

(1)实现抽象类使用extends关键字来继承抽象类

(2)子类使用关键字implements来实现接口

3.是否有构造器:

(1)抽象类可以有构造器,它属于类,有类的所有特性(但是不能实例化),包括类的构造方法。

(2)接口不能有构造器

4.子类能继承的数量:

(1)抽象类只有单继承,子类只能继承一个父类。

(2)接口就可以实现多继承,一个类可以实现多个接口

5.可使用的修饰符:

(1)抽象方法可以有public、protected这些修饰符

(2)接口方法默认修饰符是public,不可以使用其它修饰符。

6.速度方面:

抽象方法比接口速度要快

例:构造计算圆形面积的基本抽象类和接口

//Graphix.java

public abstract class Graphix {
   public abstract double area() ;
}

//Areable.java

public interface Areable {
   double area();
}

//Circle.java

/*
public class Circle extends Graphix{

	@Override
	public double area() {
		System.out.println("圆面积公式");
		return 0;
	}

}
*///分别测试运行

public class Circle implements Areable
{

	@Override
	public double area() {
		System.out.println("圆面积公式");
		return 0;
	}

}

例:Dog类同时继承自Animal抽象类并实现AnimalBehavior接口

// 抽象类
abstract class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public abstract void sound();
}

// 接口,更名为AnimalBehavior以避免命名冲突
interface AnimalBehavior {
    int ID = 1; // 接口字段默认是 static 和 final 的
    void breathe();
    void run();
}

// Dog类实现AnimalBehavior接口
class Dog implements AnimalBehavior {
    // 实现接口中的方法
    public void breathe() {
        System.out.println("Dog is breathing!");
    }
    
    public void run() {
        System.out.println("Dog is running.");
    }
    
    public void sound() {
        System.out.println("Dog barks!");
    }
}

public class Example1 {
    public static void main(String args[]) {
        Dog dog = new Dog();
        dog.breathe();
        dog.run();
        dog.sound();
    }
}

输出结果为

Dog is breathing!
Dog is running. 
Dog barks!

展示了Dog类实例化的对象调用了breatherunsound方法,并且按照这些方法中定义的打印语句输出了相应的文本。

继承与多态

继承
   修饰符 class 子类名 extends 父类名;
   类之间只能有单一继承,不支持多重继承。一个类没有明确表示继承,则默认从object类中继承。

多态是同一个行为具有多个不同表现形式或形态的能力。有两个关键因素:继承和方法重写,继承指的是子类可以继承父亲的方法和属性,方法重写指的是子类可以重写父亲中的方法,实现自己的独特属性。

class Animal { 
    public void Sound() { 
        System.out.println("Animal barks"); 
    } 
}

class Dog extends Animal { 
    public void Sound() { 
        System.out.println("Dog barks"); 
    } 
}

public class Example {
    public static void main(String[] args) { 
        Animal a1 = new Dog(); 
        a1.Sound(); // 调用Animal类中定义的Sound方法
    }
}

这段代码的输出结果为 Dog barks
      Dog类继承自Animal类并覆盖了Sound方法,所以当创建Dog类的实例并赋值给Animal类型的对象时,调用Sound方法将输出Dog barks。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值