a.使用new关键字产生对象会调用构造方法_java面向对象知识详解

一、概念

所谓面向对象是一种编程思想,通过这种思想可以吧生活中的复杂事情变的简单化,从原来的执行者变成指挥者,面向对象是基于面向过程而言的,面对对象强调结果,比如你要去上学,强调的是去学校,这个动作就是面向对象,而面向过程强调过程,强调的是你去学校的过程,比如骑自行车骑啊骑啊的去。

二、类与对象

  1. 定义 所谓类,就是将具有相似的行为或者属性的事物抽象或者集合形成一个类,就如动物类,人类,植物类 所谓对象,通常表现为实体,是类的具体实例,万物皆对象,比如动物类有猫狗这些等等
  2. 类与对象的关系 对象是类的实例,类是对象的模板
  3. 生活中的类与对象 计算机语言是用来描述现实世界事物的。属性+行为,那怎么通过java语言描述呢?通过类来描述事物,把事物的属性当做成员变量,把行为当做成员方法,比如生活中有手机这个事物,手机具有的
    属性:尺寸,品牌,价格,颜色 方法:打电话,发短信,听音乐 类:手机类,抽取属性和行为 对象:iPhone手机啊,华为手机啊,小米手机啊
  1. 类与对象的创建和使用 通过class关键字创建类,通过new关键字创建对象。
public class Test1 {
           
    
       public static void main(String[] args) {
           
    
              //p是引用对象,持有了对于Person对象的地址值的引用
              //此时的p,含有属性,但都是默认值
              Person p = new Person();
              //设置属性值
              p.name="lisi";
              p.age=20;
        //调用方法
              p.eat();
               p.sleep();
       }
}
class Person{
           
    
       //属性--成员变量
       String name;
       int age;
       //行为--方法
       void eat(){
           
    
              System.out.println("吃饭饭");
       }
       void sleep(){
           
    
              System.out.println("睡觉觉");
       }
}
public class Test1 { public static void main(String[] args) { //p是引用对象,持有了对于Person对象的地址值的引用 //此时的p,含有属性,但都是默认值 Person p = new Person(); //设置属性值 p.name="lisi"; p.age=20; //调用方法 p.eat(); p.sleep(); } } class Person{ //属性--成员变量 String name; int age; //行为--方法 void eat(){ System.out.println("吃饭饭"); } void sleep(){ System.out.println("睡觉觉"); } }

三、类与对象在内存中的存储

java内存分为5大块,推,虚拟机栈,本地方法栈,方法区,程序计数器,我们基础阶段主要学习栈,推

  1. 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
  2. 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
  3. 每个堆内存的元素都有地址值
  4. 对象中的属性都是有默认值的
  1. 在栈内存中,创建一个引用变量p,持有对象的地址值
  2. 在堆内存中,创建Person对象,并且开辟变量的空间,完成初始化
  3. 给堆内存中的元素,分配一个唯一标志,地址值。交给p去保存。
  4. p.name=”lisi”;p.age=20;就去堆内存中找唯一的地址值,找到Person对象,并对其属性进行修改赋值。
  5. p.eat();就去堆内存中找唯一的地址值,找到Person对象,执行Person对象的方法。

四、封装——面向对象的三大特征之一

封装是指隐藏对象的属性和实现细节,由private关键字修饰,当一个类的属性或者方法不想让其他类访问时,可以用private修饰,仅仅对外提供公共的访问方式。由set(),get()方法提供,封装的好处是:

  1. 提高安全性
  2. 提高重用性
class Person{
           
    
	//成员属性
	private int age;
	private String name;
	//成员方法
	void eat(){
           
    
		System.out.println("吃饭");
	}
	void sleep(){
           
    
		System.out.println("睡觉");
	}
	private void work() {
           
    
		System.out.println("上班");
	}
}
public class Text_private {
           
    

	public static void main(String[] args) {
           
    
		//在测试类里创建Perso对象
		Person person = new Person();
		
		//person.age = 18;//报错,private修饰不能使用
		//person.work();
		
		person.eat();
		person.sleep();
	}
}
class Person{ //成员属性 private int age; private String name; //成员方法 void eat(){ System.out.println("吃饭"); } void sleep(){ System.out.println("睡觉"); } private void work() { System.out.println("上班"); } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 Person person = new Person(); //person.age = 18;//报错,private修饰不能使用 //person.work(); person.eat(); person.sleep(); } }

运行结果

**解决方法:**对外提供set(),get()方法 在eclipse中,位于source栏下面的Getters and Setters,自动生成设置和获取属性的方法

class Person{
           
    
	//成员属性
	private int age;
	private String name;
	
	//获取属性的方法
	public int getAge() {
           
    
		return age;
	}
	//设置属性的方法
	public void setAge(int age) {
           
    
		this.age = age;
	}
	public String getName() {
           
    
		return name;
	}
	public void setName(String name) {
           
    
		this.name = name;
	}
	//成员方法
	void eat(){
           
    
		System.out.println("吃饭");
	}
	void sleep(){
           
    
		System.out.println("睡觉");
	}
	private void work() {
           
    
		System.out.println("上班");
	}
}
public class Text_private {
           
    

	public static void main(String[] args) {
           
    
		//在测试类里创建Perso对象
		Person person = new Person();
		person.setAge(18);
		person.setName("迪丽热巴");
		
		System.out.println(person.getAge());
		System.out.println(person.getName());
		
		person.eat();
		person.sleep();
	}
}
class Person{ //成员属性 private int age; private String name; //获取属性的方法 public int getAge() { return age; } //设置属性的方法 public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } //成员方法 void eat(){ System.out.println("吃饭"); } void sleep(){ System.out.println("睡觉"); } private void work() { System.out.println("上班"); } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 Person person = new Person(); person.setAge(18); person.setName("迪丽热巴"); System.out.println(person.getAge()); System.out.println(person.getName()); person.eat(); person.sleep(); } }

运行结果

五、构造方法

  1. 定义 构造方法也叫构造函数,构造器,构造方法是一种特殊的方法,它是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的创建或者对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载,构造方法可以自己定义也可以使用系统提供的默认构造方法。
  2. 形式 可以无参也可以有参 修饰符 类名(【参数】) { 代码…… }
  3. 练习
    构造方法创建对象 构造方法对对象初始化
class Person{
           
    
	//成员属性
	private int age;
	private String name;
	
	//无参构造方法
	Person(){}
	
	//有参构造方法
	Person(int age,String name){
           
    
		this.age = age;
		this.name = name;
	}
	@Override
	public String toString() {
           
    
		return "Person [age=" + age + ", name=" + name + "]";
	}
	
}
public class Text_private {
           
    

	public static void main(String[] args) {
           
    
		//在测试类里创建Perso对象
		//创建一个匿名对象(没有名字的对象)
		new Person();
		//创建Person对象
		Person person = new Person();
		//创建Person对象并对属性初始化
		Person person1 = new Person(18,"迪丽热巴");
		//将对象以字符串输出
		System.out.println(person1.toString());
	}
}
class Person{ //成员属性 private int age; private String name; //无参构造方法 Person(){} //有参构造方法 Person(int age,String name){ this.age = age; this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 //创建一个匿名对象(没有名字的对象) new Person(); //创建Person对象 Person person = new Person(); //创建Person对象并对属性初始化 Person person1 = new Person(18,"迪丽热巴"); //将对象以字符串输出 System.out.println(person1.toString()); } }

运行结果

六、构造代码块和局部代码块

1. 构造代码块

(1)在类的内部,方法的外部,的代码块 {} (2) 通常用于抽取构造方法中的共性代码 (3) 每次调用构造方法前都会调用构造代码块,优先于构造方法执行

public class Text2 {
           
    
	String country;
	//构造代码块
	{
           
    
		country = "中国";
	}
	//构造方法
	Text2(){
           
    
		System.out.println("1号选手来自"+country);
	}
	
	Text2(int a){
           
    
		System.out.println(a+"号选手来自"+country);
	}
	
	public static void main(String[] args) {
           
    
		Text2 t1 = new Text2();
		Text2 t2 = new Text2(2);
	}
}
public class Text2 { String country; //构造代码块 { country = "中国"; } //构造方法 Text2(){ System.out.println("1号选手来自"+country); } Text2(int a){ System.out.println(a+"号选手来自"+country); } public static void main(String[] args) { Text2 t1 = new Text2(); Text2 t2 = new Text2(2); } }

运行结果

由结果可知,先是构造代码块先执行,将country变量赋值,然后在创建对象时构造方法执行使用到country变量

2.局部代码块

1、 在方法里面的代码块 2、 通常用于控制变量的作用范围,出了括号就失效 3、 变量的范围越小越好,成员变量会有线程安全问题 4、 总结:执行顺序: 构造代码块是最优先的,局部代码块顺序执行

public class Text2 {
           
    
	{
           
    
		System.out.println("构造代码块");
	}
	Text2(){
           
    
		System.out.println("构造方法");
	}
	void method() {
           
    
		
		{
           
    System.out.println("局部代码块");}
		
	}
	
	public static void main(String[] args) {
           
    
		new Text2().method();
	}
}
public class Text2 { { System.out.println("构造代码块"); } Text2(){ System.out.println("构造方法"); } void method() { { System.out.println("局部代码块");} } public static void main(String[] args) { new Text2().method(); } }

运行结果

七、this关键字

  1. this表示当前对象的引用,比如引用当前对象的成员变量,成员方法
  2. this可以防止成员变量与局部变量名字的冲突,当传入参数和成员变量名一样时可以使用this关键字区分
  3. 在构造函数中,this()必须在第一行,表示使用自身的构造方法,根据参数来匹配调用的构造函数
//测试this关键字
public class Text_this {
           
    
	String name;
	int age;
	//参数名和成员变量一样,引用this关键字区别
	public String toString(String name,int age) {
           
    
		this.name = name;//this.name表示使用成员变量,并将参数赋值给它
		this.age = age;//如果不用this区分,根据变量使用的就近原则,则使用到的是局部变量
		return "姓名"+ this.name +",年龄"+ this.age;
	}
	
	Text_this(){
           
    
		this("赵丽颖",18);//调用自身的有参构造方法,并且只能出现在第一行
	}
	//有参构造方法
	Text_this(String str,int age){
           
    
		System.out.println("姓名"+str+",年龄"+age);
	}
	
	public static void main(String[] args) {
           
    
		System.out.println(new Text_this().toString("迪丽热巴", 18));
	}
}
//测试this关键字 public class Text_this { String name; int age; //参数名和成员变量一样,引用this关键字区别 public String toString(String name,int age) { this.name = name;//this.name表示使用成员变量,并将参数赋值给它 this.age = age;//如果不用this区分,根据变量使用的就近原则,则使用到的是局部变量 return "姓名"+ this.name +",年龄"+ this.age; } Text_this(){ this("赵丽颖",18);//调用自身的有参构造方法,并且只能出现在第一行 } //有参构造方法 Text_this(String str,int age){ System.out.println("姓名"+str+",年龄"+age); } public static void main(String[] args) { System.out.println(new Text_this().toString("迪丽热巴", 18)); } }

运行结果

八、继承

1.概念

继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类(子类),子类能继承已有类的数据属性和行为,并能扩展新的能力。

Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类/超类/基类,只能继承一个父类,Java只支持单继承。

这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。提高复用性:只要继承父类,就能有一样的功能

2.特点

  1. 使用extends关键字
  2. 相当于子类把父类的功能复制了一份
  3. java只支持单继承
  4. 继承可以传递(爷爷,儿子,孙子的关系)
  5. 不能继承父类的私有成员
  6. 继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展

语法: class A extends B { }

//父类
class Parent{
           
    
	int age;
	String name;
	void eat() {
           
    
		System.out.println("吃饭");
	}
	void sleep() {
           
    
		System.out.println("睡觉");
	}
}

//子类
class Son extends Parent{
           
    
	//子类可以拥有从父类继承到的属性和方法
}

public class Text {
           
    

	public static void main(String[] args) {
           
    
		//创建子类对象
		Son son = new Son();
		//访问从父类继承的属性和方法
		son.age = 18;
		son.name  = "张三";
		System.out.println(son.age +" " + son.name);
		son.eat();
		son.sleep();	
	}
}
//父类 class Parent{ int age; String name; void eat() { System.out.println("吃饭"); } void sleep() { System.out.println("睡觉"); } } //子类 class Son extends Parent{ //子类可以拥有从父类继承到的属性和方法 } public class Text { public static void main(String[] args) { //创建子类对象 Son son = new Son(); //访问从父类继承的属性和方法 son.age = 18; son.name = "张三"; System.out.println(son.age +" " + son.name); son.eat(); son.sleep(); } }

运行结果

3.super关键字

    super表示父类的一个引用对象,通过super关键字可以使用父类的内容,如super.name,访问父类的成员变量 如果用super(),必须出现在调用位置的第一行,表示使用父类的无参构造 子类创建对象时,父类的无参构造方法也会运行,因为在子类的构造方法中,有一个默认的隐式super()语句 子类使用super()调用父类的构造方法时,必须在子类的构造方法中使用,并且只能使用一次
class Fu{
           
    
	int age;
	String name;
	
	public Fu() {
           
    
		System.out.println("父类的无参构造方法");
	}

	Fu(int age,String name){
           
    
		this.age = age;
		this.name = name;
		System.out.println("父类的有参构造方法");
	}
}

class Zi extends Fu{
           
    
	
	Zi(){
           
    
		super(18,"父");
		//super();//注:不能同时调用父类的几个构造方法
		//访问父类的属性
		System.out.println(super.age);
		System.out.println(super.name);
	}
}
public class Text_super {
           
    

	public static void main(String[] args) {
           
    
		new Zi();
	}

}
class Fu{ int age; String name; public Fu() { System.out.println("父类的无参构造方法"); } Fu(int age,String name){ this.age = age; this.name = name; System.out.println("父类的有参构造方法"); } } class Zi extends Fu{ Zi(){ super(18,"父"); //super();//注:不能同时调用父类的几个构造方法 //访问父类的属性 System.out.println(super.age); System.out.println(super.name); } } public class Text_super { public static void main(String[] args) { new Zi(); } }

九、static关键字

    作用范围:可以修饰成员变量,成员方法,使用static修饰后属于类资源,而不再属于对象,随着类的加载而加载 特点:只加载一次,随着类的加载类的消失而消失,静态资源只能访问静态资源不能访问非静态资源,非静态资源既可以访问静态资源,又可以访问静态资源,static不能和this,super关键字一起使用,因为类存在时对象可能还没创建,并且static资源优先于对象存在 静态代码块:static修饰的代码块称为静态代码块 调用:可以直接使用类名调用,在本类中使用静态资源可以省略类名
public class Text_static {
           
    
	int age;
	static String country = "中国";//静态资源——类变量
	public static void main(String[] args) {
           
    
		method();
		Text_static.method1();
		
	}
	private static void method1() {
           
    
		System.out.println("静态方法");
	}
	//静态资源——静态方法
	private static void method() {
           
    
		System.out.println("来自"+country);
		//System.out.println(age);静态不能访问非静态
	}
}
public class Text_static { int age; static String country = "中国";//静态资源——类变量 public static void main(String[] args) { method(); Text_static.method1(); } private static void method1() { System.out.println("静态方法"); } //静态资源——静态方法 private static void method() { System.out.println("来自"+country); //System.out.println(age);静态不能访问非静态 } }

运行结果

静态代码块,构造代码块,构造方法,局部代码块,静态方法的执行顺序 1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化

2、 构造代码块:在调用构造方法前会自动调用,每次创建对象都会被调用

3、 局部代码块:方法里的代码块,方法被调用时才会执行

4、 静态代码块:static{ },位置:在类里方法外

public class Text {
           
    
	
	public static void main(String[] args) {
           
    
		new Text_staticSequence().method();
		System.out.println("_________________");
		new Text_staticSequence().method1();
	}
}
class Text_staticSequence {
           
    
	//构造代码块
	{
           
    
		System.out.println("构造代码块");
	}
		
	//构造方法
	public Text_staticSequence() {
           
    
		System.out.println("构造方法");
	}
	//静态方法	
	public static void method() {
           
    
		System.out.println("静态方法");
	}

	//静态代码块
	static {
           
    
		System.out.println("静态代码块");
	}
	
	//普通方法
	void method1(){
           
    
		System.out.println("普通方法");
		//局部代码块
		{
           
    
			System.out.println("局部代码块");
		}
	}
	
}
public class Text { public static void main(String[] args) { new Text_staticSequence().method(); System.out.println("_________________"); new Text_staticSequence().method1(); } } class Text_staticSequence { //构造代码块 { System.out.println("构造代码块"); } //构造方法 public Text_staticSequence() { System.out.println("构造方法"); } //静态方法 public static void method() { System.out.println("静态方法"); } //静态代码块 static { System.out.println("静态代码块"); } //普通方法 void method1(){ System.out.println("普通方法"); //局部代码块 { System.out.println("局部代码块"); } } }

运行结果

由运行结果可以得出

    执行顺序为:静态代码块>构造代码块>构造方法>静态方法/局部代码块 测试中,创建了两次对象,但是静态代码块只执行一次,构造代码块与构造方法随着创建对象而运行 静态方法与局部代码块需要对象调用,所以最后才运行

使用static关键字

  1. static可以修饰类(最终类),但是不能被继承
  2. static可以修饰变量(常量),但是值不能被修改
  3. static可以修饰方法(最终方法),但是不能被重写

十、多态

  1. 概述 多态,通常描述的是对象,即对象的不同状态 比如猫既有猫类自己的状态,又有动物类的状态,主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。
  2. 对象构成多态的条件
    必须要发生继承关系 必须存在方法的覆盖 必须有父类引用指向子类对象
  1. 多态的特点
    编译看左边,运行看右边 说明:即只能使用父类提供的方法,不能使用子类特有的方法,否则不能通过,运行时看右边,即看new的对象,如Animal a = new Cat();则使用的是Cat里面的方法 多态使用的成员变量是父类的成员变量 多态里的静态方法不能被重写
/**
 * 多态:
 * 前提:继承关系,方法重写
 * 口诀:父类引用 指向 子类对象(向上转型)
 * @author TEDU
 */
public class Text1 {
           
    
	public static void main(String[] args) {
           
    
		Animal a = new Cat();//编译看左边,运行看右边,
		                      //只能使用父类提供的,运行时看new的对象,
		                      //即不能使用子类特有的方法
		a.eat();
		a.sleep();
		a.catchFood();
		System.out.println(a.age+a.name);//多态使用的是父类成员
		a.show();//静态方法不可以重写
		
	}
}
class Animal{
           
    
	int age;
	String name;
	Animal(){
           
    
		this.age = 18;
		this.name = "动物";
	}
	public void eat() {
           
    
		System.out.println("吃饭");
	}

	public void sleep() {
           
    
		System.out.println("睡觉");
	}
	public void catchFood() {
           
    
		System.out.println("捕食");
	}
	public static void show() {
           
    
		System.out.println(1);
	}
}
class Cat extends Animal{
           
    
	public void eat() {
           
    
		System.out.println("猫吃鱼");
	}
	public void sleep() {
           
    
		System.out.println("猫睡觉");
	}
	public static void show() {
           
    
		System.out.println(2);
	}
}
/** * 多态: * 前提:继承关系,方法重写 * 口诀:父类引用 指向 子类对象(向上转型) * @author TEDU */ public class Text1 { public static void main(String[] args) { Animal a = new Cat();//编译看左边,运行看右边, //只能使用父类提供的,运行时看new的对象, //即不能使用子类特有的方法 a.eat(); a.sleep(); a.catchFood(); System.out.println(a.age+a.name);//多态使用的是父类成员 a.show();//静态方法不可以重写 } } class Animal{ int age; String name; Animal(){ this.age = 18; this.name = "动物"; } public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } public void catchFood() { System.out.println("捕食"); } public static void show() { System.out.println(1); } } class Cat extends Animal{ public void eat() { System.out.println("猫吃鱼"); } public void sleep() { System.out.println("猫睡觉"); } public static void show() { System.out.println(2); } }

十一、抽象类

  1. 抽象方法 当不需要强调方法的具体实现细节,或者方法中没有具体实现意义,如动物类里面有个吃饭的方法,但是又不知道具体实现,可以将方法定义为抽象方法,抽象方法没有方法体,其具体实现由子类去重写。
  2. 抽象类 由abstract关键字修饰的类叫抽象类,抽象方法只能存在于抽象类中,抽象类中既有抽象方法,也可以有普通方法。
  3. 抽象类与抽象方法的特点
    抽象类不可以创建对象(不能别实例化),由子类继承抽象类去实现抽象类里的方法 抽象类有构造方法,但是不可以创建对象,主要为子类提供多态功能 抽象方法没有方法体,并且只能存在于抽象类中 继承抽象类的类必须要重写抽象类里的所有抽象方法
package cn.tedu.day09;

public class Text2 {
           
    
	public static void main(String[] args) {
           
    
		//Animal an = new Animal();错误,抽象类不能实例化
		Animal cat = new Cat();//多态
		cat.catchFood();
		cat.eat();
		cat.sleep();
	}
}
//抽象类
abstract class Animal{
           
    
	//构造方法
	Animal(){
           
    
		System.out.println("动物类祖先");
	}
	//抽象方法
	public abstract void eat() ;
	public abstract void catchFood();
	//非抽象方法
	public void sleep() {
           
    
		System.out.println("冬眠");
	}
}
//非抽象类
class Cat extends Animal{
           
    

	@Override
	public void eat() {
           
    
		System.out.println("猫吃鱼");
	}

	@Override
	public void catchFood() {
           
    
		System.out.println("猫捉老鼠");
	}
}
package cn.tedu.day09; public class Text2 { public static void main(String[] args) { //Animal an = new Animal();错误,抽象类不能实例化 Animal cat = new Cat();//多态 cat.catchFood(); cat.eat(); cat.sleep(); } } //抽象类 abstract class Animal{ //构造方法 Animal(){ System.out.println("动物类祖先"); } //抽象方法 public abstract void eat() ; public abstract void catchFood(); //非抽象方法 public void sleep() { System.out.println("冬眠"); } } //非抽象类 class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void catchFood() { System.out.println("猫捉老鼠"); } }

小练习 模拟老师教书,要求使用抽象类,有教基础的和教框架的老师

package cn.tedu.day09;

public class Text4 {
           
    
	public static void main(String[] args) {
           
    
		//javase老师
		Teacher t1 = new Teacher1();
		t1.setAge(20);
		t1.setName("渣渣");
		System.out.println(t1.getAge()+t1.getName());
		t1.teach();
		
		//javaee老师
		Teacher t2 = new Teacher2();
		t2.setAge(28);
		t2.setName("大牛");
		System.out.println(t2.getAge()+t2.getName());
		t2.teach();
	}
}
//老师类
abstract class Teacher{
           
    
	private String name;
	private int age;
	
	public String getName() {
           
    
		return name;
	}
	public void setName(String name) {
           
    
		this.name = name;
	}
	public int getAge() {
           
    
		return age;
	}
	public void setAge(int age) {
           
    
		this.age = age;
	}
	abstract void teach();//教书方法
}

//javase老师
class Teacher1 extends Teacher{
           
    
	@Override
	void teach() {
           
    
		System.out.println("教java基础");
	}	
} 

//javaee老师
class Teacher2 extends Teacher{
           
    
	@Override
	void teach() {
           
    
		System.out.println("教java框架");
	}
}
package cn.tedu.day09; public class Text4 { public static void main(String[] args) { //javase老师 Teacher t1 = new Teacher1(); t1.setAge(20); t1.setName("渣渣"); System.out.println(t1.getAge()+t1.getName()); t1.teach(); //javaee老师 Teacher t2 = new Teacher2(); t2.setAge(28); t2.setName("大牛"); System.out.println(t2.getAge()+t2.getName()); t2.teach(); } } //老师类 abstract class Teacher{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } abstract void teach();//教书方法 } //javase老师 class Teacher1 extends Teacher{ @Override void teach() { System.out.println("教java基础"); } } //javaee老师 class Teacher2 extends Teacher{ @Override void teach() { System.out.println("教java框架"); } }

更新中… …

一、概念 所谓面向对象是一种编程思想,通过这种思想可以吧生活中的复杂事情变的简单化,从原来的执行者变成指挥者,面向对象是基于面向过程而言的,面对对象强调结果,比如你要去上学,强调的是去学校,这个动作就是面向对象,而面向过程强调过程,强调的是你去学校的过程,比如骑自行车骑啊骑啊的去。 二、类与对象 定义 所谓类,就是将具有相似的行为或者属性的事物抽象或者集合形成一个类,就如动物类,人类,植物类 所谓对象,通常表现为实体,是类的具体实例,万物皆对象,比如动物类有猫狗这些等等 类与对象的关系 对象是类的实例,类是对象的模板 生活中的类与对象 计算机语言是用来描述现实世界事物的。属性+行为,那怎么通过java语言描述呢?通过类来描述事物,把事物的属性当做成员变量,把行为当做成员方法,比如生活中有手机这个事物,手机具有的 属性:尺寸,品牌,价格,颜色 方法:打电话,发短信,听音乐 类:手机类,抽取属性和行为 对象:iPhone手机啊,华为手机啊,小米手机啊 类与对象的创建和使用 通过class关键字创建类,通过new关键字创建对象。 public class Test1 { public static void main(String[] args) { //p是引用对象,持有了对于Person对象的地址值的引用 //此时的p,含有属性,但都是默认值 Person p = new Person(); //设置属性值 p.name="lisi"; p.age=20; //调用方法 p.eat(); p.sleep(); } } class Person{ //属性--成员变量 String name; int age; //行为--方法 void eat(){ System.out.println("吃饭饭"); } void sleep(){ System.out.println("睡觉觉"); } } 三、类与对象在内存中的存储 java内存分为5大块,推,虚拟机栈,本地方法栈,方法区,程序计数器,我们基础阶段主要学习栈,推 一般来讲局部变量存在栈中,方法执行完毕内存就被释放 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放 每个堆内存的元素都有地址值 对象中的属性都是有默认值的 在栈内存中,创建一个引用变量p,持有对象的地址值 在堆内存中,创建Person对象,并且开辟变量的空间,完成初始化 给堆内存中的元素,分配一个唯一标志,地址值。交给p去保存。 p.name=”lisi”;p.age=20;就去堆内存中找唯一的地址值,找到Person对象,并对其属性进行修改赋值。 p.eat();就去堆内存中找唯一的地址值,找到Person对象,执行Person对象的方法。 四、封装——面向对象的三大特征之一 封装是指隐藏对象的属性和实现细节,由private关键字修饰,当一个类的属性或者方法不想让其他类访问时,可以用private修饰,仅仅对外提供公共的访问方式。由set(),get()方法提供,封装的好处是: 提高安全性 提高重用性 class Person{ //成员属性 private int age; private String name; //成员方法 void eat(){ System.out.println("吃饭"); } void sleep(){ System.out.println("睡觉"); } private void work() { System.out.println("上班"); } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 Person person = new Person(); //person.age = 18;//报错,private修饰不能使用 //person.work(); person.eat(); person.sleep(); } } 运行结果 **解决方法:**对外提供set(),get()方法 在eclipse中,位于source栏下面的Getters and Setters,自动生成设置和获取属性的方法 class Person{ //成员属性 private int age; private String name; //获取属性的方法 public int getAge() { return age; } //设置属性的方法 public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } //成员方法 void eat(){ System.out.println("吃饭"); } void sleep(){ System.out.println("睡觉"); } private void work() { System.out.println("上班"); } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 Person person = new Person(); person.setAge(18); person.setName("迪丽热巴"); System.out.println(person.getAge()); System.out.println(person.getName()); person.eat(); person.sleep(); } } 运行结果 五、构造方法 定义 构造方法也叫构造函数,构造器,构造方法是一种特殊的方法,它是一个与类同名且没有返回值类型的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的创建或者对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载,构造方法可以自己定义也可以使用系统提供的默认构造方法。 形式 可以无参也可以有参 修饰符 类名(【参数】) { 代码…… } 练习 构造方法创建对象 构造方法对对象初始化 class Person{ //成员属性 private int age; private String name; //无参构造方法 Person(){} //有参构造方法 Person(int age,String name){ this.age = age; this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } } public class Text_private { public static void main(String[] args) { //在测试类里创建Perso对象 //创建一个匿名对象(没有名字的对象) new Person(); //创建Person对象 Person person = new Person(); //创建Person对象并对属性初始化 Person person1 = new Person(18,"迪丽热巴"); //将对象以字符串输出 System.out.println(person1.toString()); } } 运行结果 六、构造代码块和局部代码块 1. 构造代码块 (1)在类的内部,方法的外部,的代码块 {} (2) 通常用于抽取构造方法中的共性代码 (3) 每次调用构造方法前都会调用构造代码块,优先于构造方法执行 public class Text2 { String country; //构造代码块 { country = "中国"; } //构造方法 Text2(){ System.out.println("1号选手来自"+country); } Text2(int a){ System.out.println(a+"号选手来自"+country); } public static void main(String[] args) { Text2 t1 = new Text2(); Text2 t2 = new Text2(2); } } 运行结果 由结果可知,先是构造代码块先执行,将country变量赋值,然后在创建对象时构造方法执行使用到country变量 2.局部代码块 1、 在方法里面的代码块 2、 通常用于控制变量的作用范围,出了括号就失效 3、 变量的范围越小越好,成员变量会有线程安全问题 4、 总结:执行顺序: 构造代码块是最优先的,局部代码块顺序执行 public class Text2 { { System.out.println("构造代码块"); } Text2(){ System.out.println("构造方法"); } void method() { { System.out.println("局部代码块");} } public static void main(String[] args) { new Text2().method(); } } 运行结果 七、this关键字 this表示当前对象的引用,比如引用当前对象的成员变量,成员方法 this可以防止成员变量与局部变量名字的冲突,当传入参数和成员变量名一样时可以使用this关键字区分 在构造函数中,this()必须在第一行,表示使用自身的构造方法,根据参数来匹配调用的构造函数 //测试this关键字 public class Text_this { String name; int age; //参数名和成员变量一样,引用this关键字区别 public String toString(String name,int age) { this.name = name;//this.name表示使用成员变量,并将参数赋值给它 this.age = age;//如果不用this区分,根据变量使用的就近原则,则使用到的是局部变量 return "姓名"+ this.name +",年龄"+ this.age; } Text_this(){ this("赵丽颖",18);//调用自身的有参构造方法,并且只能出现在第一行 } //有参构造方法 Text_this(String str,int age){ System.out.println("姓名"+str+",年龄"+age); } public static void main(String[] args) { System.out.println(new Text_this().toString("迪丽热巴", 18)); } } 运行结果 八、继承 1.概念 继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类(子类),子类能继承已有类的数据属性和行为,并能扩展新的能力。 Java继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类/超类/基类,只能继承一个父类,Java只支持单继承。 这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。提高复用性:只要继承父类,就能有一样的功能 2.特点 使用extends关键字 相当于子类把父类的功能复制了一份 java只支持单继承 继承可以传递(爷爷,儿子,孙子的关系) 不能继承父类的私有成员 继承多用于功能的修改,子类可以拥有父类的功能的同时,进行功能拓展 语法: class A extends B { } //父类 class Parent{ int age; String name; void eat() { System.out.println("吃饭"); } void sleep() { System.out.println("睡觉"); } } //子类 class Son extends Parent{ //子类可以拥有从父类继承到的属性和方法 } public class Text { public static void main(String[] args) { //创建子类对象 Son son = new Son(); //访问从父类继承的属性和方法 son.age = 18; son.name = "张三"; System.out.println(son.age +" " + son.name); son.eat(); son.sleep(); } } 运行结果 3.super关键字 super表示父类的一个引用对象,通过super关键字可以使用父类的内容,如super.name,访问父类的成员变量 如果用super(),必须出现在调用位置的第一行,表示使用父类的无参构造 子类创建对象时,父类的无参构造方法也会运行,因为在子类的构造方法中,有一个默认的隐式super()语句 子类使用super()调用父类的构造方法时,必须在子类的构造方法中使用,并且只能使用一次 class Fu{ int age; String name; public Fu() { System.out.println("父类的无参构造方法"); } Fu(int age,String name){ this.age = age; this.name = name; System.out.println("父类的有参构造方法"); } } class Zi extends Fu{ Zi(){ super(18,"父"); //super();//注:不能同时调用父类的几个构造方法 //访问父类的属性 System.out.println(super.age); System.out.println(super.name); } } public class Text_super { public static void main(String[] args) { new Zi(); } } 九、static关键字 作用范围:可以修饰成员变量,成员方法,使用static修饰后属于类资源,而不再属于对象,随着类的加载而加载 特点:只加载一次,随着类的加载类的消失而消失,静态资源只能访问静态资源不能访问非静态资源,非静态资源既可以访问静态资源,又可以访问静态资源,static不能和this,super关键字一起使用,因为类存在时对象可能还没创建,并且static资源优先于对象存在 静态代码块:static修饰的代码块称为静态代码块 调用:可以直接使用类名调用,在本类中使用静态资源可以省略类名 public class Text_static { int age; static String country = "中国";//静态资源——类变量 public static void main(String[] args) { method(); Text_static.method1(); } private static void method1() { System.out.println("静态方法"); } //静态资源——静态方法 private static void method() { System.out.println("来自"+country); //System.out.println(age);静态不能访问非静态 } } 运行结果 静态代码块,构造代码块,构造方法,局部代码块,静态方法的执行顺序 1、 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化 2、 构造代码块:在调用构造方法前会自动调用,每次创建对象都会被调用 3、 局部代码块:方法里的代码块,方法被调用时才会执行 4、 静态代码块:static{ },位置:在类里方法外 public class Text { public static void main(String[] args) { new Text_staticSequence().method(); System.out.println("_________________"); new Text_staticSequence().method1(); } } class Text_staticSequence { //构造代码块 { System.out.println("构造代码块"); } //构造方法 public Text_staticSequence() { System.out.println("构造方法"); } //静态方法 public static void method() { System.out.println("静态方法"); } //静态代码块 static { System.out.println("静态代码块"); } //普通方法 void method1(){ System.out.println("普通方法"); //局部代码块 { System.out.println("局部代码块"); } } } 运行结果 由运行结果可以得出 执行顺序为:静态代码块>构造代码块>构造方法>静态方法/局部代码块 测试中,创建了两次对象,但是静态代码块只执行一次,构造代码块与构造方法随着创建对象而运行 静态方法与局部代码块需要对象调用,所以最后才运行 使用static关键字 static可以修饰类(最终类),但是不能被继承 static可以修饰变量(常量),但是值不能被修改 static可以修饰方法(最终方法),但是不能被重写 十、多态 概述 多态,通常描述的是对象,即对象的不同状态 比如猫既有猫类自己的状态,又有动物类的状态,主要是指同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态。 对象构成多态的条件 必须要发生继承关系 必须存在方法的覆盖 必须有父类引用指向子类对象 多态的特点 编译看左边,运行看右边 说明:即只能使用父类提供的方法,不能使用子类特有的方法,否则不能通过,运行时看右边,即看new的对象,如Animal a = new Cat();则使用的是Cat里面的方法 多态使用的成员变量是父类的成员变量 多态里的静态方法不能被重写 /** * 多态: * 前提:继承关系,方法重写 * 口诀:父类引用 指向 子类对象(向上转型) * @author TEDU */ public class Text1 { public static void main(String[] args) { Animal a = new Cat();//编译看左边,运行看右边, //只能使用父类提供的,运行时看new的对象, //即不能使用子类特有的方法 a.eat(); a.sleep(); a.catchFood(); System.out.println(a.age+a.name);//多态使用的是父类成员 a.show();//静态方法不可以重写 } } class Animal{ int age; String name; Animal(){ this.age = 18; this.name = "动物"; } public void eat() { System.out.println("吃饭"); } public void sleep() { System.out.println("睡觉"); } public void catchFood() { System.out.println("捕食"); } public static void show() { System.out.println(1); } } class Cat extends Animal{ public void eat() { System.out.println("猫吃鱼"); } public void sleep() { System.out.println("猫睡觉"); } public static void show() { System.out.println(2); } } 十一、抽象类 抽象方法 当不需要强调方法的具体实现细节,或者方法中没有具体实现意义,如动物类里面有个吃饭的方法,但是又不知道具体实现,可以将方法定义为抽象方法,抽象方法没有方法体,其具体实现由子类去重写。 抽象类 由abstract关键字修饰的类叫抽象类,抽象方法只能存在于抽象类中,抽象类中既有抽象方法,也可以有普通方法。 抽象类与抽象方法的特点 抽象类不可以创建对象(不能别实例化),由子类继承抽象类去实现抽象类里的方法 抽象类有构造方法,但是不可以创建对象,主要为子类提供多态功能 抽象方法没有方法体,并且只能存在于抽象类中 继承抽象类的类必须要重写抽象类里的所有抽象方法 package cn.tedu.day09; public class Text2 { public static void main(String[] args) { //Animal an = new Animal();错误,抽象类不能实例化 Animal cat = new Cat();//多态 cat.catchFood(); cat.eat(); cat.sleep(); } } //抽象类 abstract class Animal{ //构造方法 Animal(){ System.out.println("动物类祖先"); } //抽象方法 public abstract void eat() ; public abstract void catchFood(); //非抽象方法 public void sleep() { System.out.println("冬眠"); } } //非抽象类 class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void catchFood() { System.out.println("猫捉老鼠"); } } 小练习 模拟老师教书,要求使用抽象类,有教基础的和教框架的老师 package cn.tedu.day09; public class Text4 { public static void main(String[] args) { //javase老师 Teacher t1 = new Teacher1(); t1.setAge(20); t1.setName("渣渣"); System.out.println(t1.getAge()+t1.getName()); t1.teach(); //javaee老师 Teacher t2 = new Teacher2(); t2.setAge(28); t2.setName("大牛"); System.out.println(t2.getAge()+t2.getName()); t2.teach(); } } //老师类 abstract class Teacher{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } abstract void teach();//教书方法 } //javase老师 class Teacher1 extends Teacher{ @Override void teach() { System.out.println("教java基础"); } } //javaee老师 class Teacher2 extends Teacher{ @Override void teach() { System.out.println("教java框架"); } } 更新中… …
经验分享 程序员 微信小程序 职场和发展