对象与封装
一、面向对象编程
1.设计步骤:①发现类;②发现类的属性;③发现类的方法
2.类的三大特性:封装、继承、多态
3.注意:面向对象的核心是封装了属性和方法的类,侧重的是数据本身,实现了类级别的代码重用。
二、构造方法其重载
1.作用:new对象,兼职:给成员变量赋值
2.语法:访问修饰符 类名(参数){}
3.分类:
参数个数:有参和无参
显示分式:显示和隐式
4.注意:一个类中若没有手写构造函数,那么这个类一定存在隐藏的无参构造函数,一旦手写了构造函数,这个类就不存在无参构造函数了,也可以显式的定义无参构造函数。
5.重载的特点:在同一个类中,具有相同的方法名,不同的参数个数和对应参数的下标数据类型不同。
//构造函数的重载
public class Calc{
public Calc(){}
public Calc(int num1,int num2){}
public Calc(int num1,double num2){}
}
三、关键字
1.final常量修饰符
修饰变量:常量;特点:声明常量必须赋值,赋值后不能修改。
注意:如果是引用类型,表示引用不可变,但是属性值可以改变
//赋值后不能修改
public class A {
final int x=10;
x++; //错误
}
//引用不可以变,但是属性值可以改变
Cat c1 =new Cat();
c1.name="cat1"; //可以修改成功
c1=new Cat(); //错误
Cat c2 =new Cat();
c1=c2; //错误
重点:final可以修饰静态变量,实例变量和局部变量,分别为静态常量,实例常量和局部常量。
public class A {
final static int MAX = 100; //静态常量
final int MIN = 0; //非静态常量
void method() {
final int var = 1; //局部常量
}
}
修饰方法:特点:方法不能被重写。
public class Person{
public final void method(){}
}
public class Student extends Person{
@Oveerride
public void method(){} //错误
}
修饰类:特点:被修饰的类不能被继承,类似于C#中的密封类sealed。
public final class Person{}
public class Student extends Person{} //错误
①特点:静态成员属于类,但是也可以通过对象名去访问。
②区别C#:C#中static只能通过类名访问,Java中的static成员建议通过类名访问,也可以通过对象名访问,但是不建议使用对象名访问因为static成员属于类成员而非对象成员。
③修饰的成员:字段==》静态字段,可以通过类名访问,也可以通过对象名访问。
方法==》静态方法,可以通过类名访问,也可以通过对象名访问。
//使用static关键字修饰字段
class Student{
//使用了static修饰country,那么这时候country就是一个共享的数据。
static String country = "中国"; //国籍
}
class Demo {
public static void main(String[] args)
{
Student s1 = new Student();
s1.country = "美国";
System.out.println(" 国籍:"+ s1.country); // 输出美国,因为static成员属于类
}
//使用static关键字修饰方法
public class Printer {
public static void print(){
System.out.println("你好");
}
public static void main(String[] args) {
//通过类名调用静态方法
Printer.print(); //你好
//通过对象调用静态方法
Printer printer = new Printer();
printer.print(); //你好
}
}
注意:静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如果希望在静态方法中调用非静态变量,可以通过创建对象,然后通过对象来访问非静态变量。
类:static不能修饰普通类会出现编译错误,但是可以修饰内部类。
//外部类
public class Out{
private static String name = "zhangsan";
//内部类
private static class Inner{
public Inner(){
System.out.println(name); // 访问外部类的私有静态字段
}
}
静态块:static{}
特点:在某个类加载的时候始终只执行一次,如果类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。
public class Person{
public Person() {
System.out.println("我是无参构造函数!");
}
static {
System.out.println("我是静态块!");
}
public static void main(String[] args) {
Person per =new Person();
}
}
//输出:我是静态块!
//我是无参构造函数!
3.this和super
this:当前类的对象的引用;super:对父类对象的引用
注意:静态方法中不能出现this ,super 关键字。
继承和多态
一、继承
1.定义:子类继承父类,将具有相同行为的类的代码提取为一个公共类,所以描述的是两个类之间的关系。
子类:继承的类,又叫派生类;父类:被继承的类,又叫超类和基类。
2.语法:区别C#,C#使用字符“:”描述继承,在Java中使用extends描述继承。
class 子类 extends 父类
public class Person{}
public class Student extends Person{}
3.继承的特性:①单根性:一个孩子只有一个亲生父亲,即一个类只有有一个父类。注意:默认的父类是object。
②传递性:孙类可以拥有父类的行为。
4.子类和父类之间的关系:
①访问修饰符:
访问修饰符 | 本类 | 子类(同包) | 不同包 | 其它位置 |
---|---|---|---|---|
public | 可以 | 可以 | 可以 | 可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
friendly | 可以 | 可以 | 不可以 | 不可以 |
private | 可以 | 不可以 | 不可以 | 不可以 |
注意:通过对象访问的时候,如果是同一个包,只有private访问不到,在不同的包只能访问到public成员。
②构造函数
1.子父类关系:调用子类构造函数时候一定会调用父类的构造函数,默认情况下,子类会调用父类的无参构造函数。
2.子类怎么显示调用父类的构造函数?
使用super(参数)关键字,在方法体中调用父类的构造函数。
public class Person{
public String name;
public int age;
public Person(){}
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
public class Student extends Person{
public Student(String name,int age){
super(name,age); //调用父类的有参数构造函数
}
}
3.如何调用自身的构造函数?
使用this(参数)关键字,在方法体中调用父类的构造函数。
注意:在构造函数中如果有this语句或super语句出现,则只能是第一条语句。那么,在一个构造函数中也不能同时使用this和super语句。
③子类可以访问到所有父类非私有行为。
5.继承的优缺点:
优点:①提高的重用性;②子类可以扩展自己功能–》子类可以形似父类,还可以具有自我特性。
缺点:①继承是一种侵入式编程;②增加耦合,父类拥有的子类一定有,父类一旦被修改一定会影响子类,那么父类约束了子类。
二、多态
1.定义:一个事务的多种形态。
2.实现方式:重载和重写
3.重载:
特点:在同一个类中,方法名相同,参数个数不同或者参数对应的下标的数据类型不同。
注意:和返回值类型无关。
public class Printer{
public void print(int i) {……}
public void print(float f) {……}
public void print(String s) {……}
}
4.重写:
1.前提:继承关系
2.特点:①在不同的类中,方法名相同,参数列表相同。
②访问修饰符:子类的访问修饰符不能缩小,即子类的访问修饰符要大于等于父类的访问修饰符级别。
③返回值类型:父类的返回值类型要大于等于子类的返回值类型,注意是属于关系,不是兼容关系。
④抛出异常:父类要大于等于子类。
3.实现重写:
①满足重写的特点直接重写即可,注解可省略不写,写的话是方便程序员知道这里是重写的方法。
public class Person{
public void SayHi(){
System.out.println("这里是父类的介绍方法!");
}
}
public class Student extends Person{
@Override
public void SayHi(){
System.out.println("这里是子类的介绍方法!");
}
}
//注意子类的访问修饰符要大于等于父类的访问修饰符
public class Person{
public void SayHi(){
System.out.println("这里是父类的介绍方法!");
}
}
public class Student extends Person{
//注解可以省略不写
private void SayHi(){
System.out.println("这里是子类的介绍方法!"); //错误,子类的访问修饰符不能缩小
}
}
②抽象方法:特点:必须位于抽象类中;抽象方法没有方法体;子类必须重写父类的抽象方法,除非子类也是抽象类。
抽象类特点:Ⅰ、使用关键字abstract定义类,并且抽象类不能被实例化,但是可以有构造函数。
Ⅱ、抽象类中可以普通方法,也可以有抽象方法。
public abstract class Person{
public abstract void SayHi(); //抽象方法
}
public class Student extends Person{
@Override
public void SayHi(){
System.out.println("这里是子类的介绍方法!"); //子类必须重写,否则编译报错
}
}
4.区别C#:
①在C#中,重写父类的方法子类一定要显示定义override,父类显示定义virtual虚方法。
②在java中实现重写:方法名相同,参数相同即可。
5.向上转型和向下转型
向上转型:子类转换为父类
Father fa = new Child(); //向上转型--》子类对象赋值给父类引用
向下转型:父类转换为子类
Child child = (Child)fa; //向下转型--》将一个父类对象名强转为子类
判断一个变量的真实数据类型使用关键字:instanceof
//Pet是宠物类父类,Dog和Penguin是狗类和企鹅类是Pet的子类
public static void main(String[] args) {
//父类引用的指向子类的对象,指向的是企鹅类
//向上转型
Pet pet =new Penguin("楠楠","Q妹");
pet.eat();
if(pet instanceof Dog) {
Dog dog =(Dog)pet; //向下转型
dog.catchingFlyDisc(); //狗狗接住飞盘的方法
}else if(pet instanceof Penguin) { //该表达式为True进入这个if语句
Penguin pgn =(Penguin)pet;
pgn.swimming(); //企鹅游泳的方法
}
}
接口
一、定义
1.定义:接口表示一种能力,一种约定,只要求对象具备某些功能并不影响对象的本质。
2.语法:public interface 接口名 extends 父接口1,父接口2,…{}
3.特点:①不能被实例化,并且没有构造函数;
②成员方法:只能是抽象方法,使用关键字abstract,默认访问修饰符:public abstract
③成员变量:只能定义静态常量,默认访问修饰符: public static final
注意:接口中的成员都是public,不能缩小其访问修饰符范围。
4.作用:约束子类必须拥有某种行为
public interface TakePhotos {
void Picture(); //拍照功能
}
5.实现接口:运用关键字implements
语法:class 类名 extends 父类名 implements 接口1、接口2,…{}
//实现接口
public class Phone implements TakePhotos{
public Phone() {
this.brand="华为";
}
private String brand;
//必须重写
@Override
public void Picture() {
System.out.println("这是一部"+this.brand+"手机正在拍照!");
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
二、接口和抽象类的区别
1、相同点:
①都不能被实例化;
②约束子类必须实现抽象方法,除非子类也是抽象类、接口。
2、不同点
①关键字:抽象类:abstract;接口:interface;
②接口只能有抽象方法;抽象类可以有抽象方法,也可以有普通方法;
③接口不能有构造函数;抽象类可以有构造函数;
④成员变量:抽象类可以有非静态的,可以不是常量;接口中的成员变量都是默认修饰符static final。
三、C#中的接口
1.流程无区别:关键字interface定义接口
2.实现:
语法:子类:父类,接口
定义:属性默认:public static const,不能显示定义;方法:public abstract ,同样不能显示定义。
注意:C#接口中不能定义变量,只能定义属性。
public interface Paper
{
//定义属性
string Size { get; }
void Show();
}
//实现接口
public class A4Paper : Paper
{
public string Size { get { return "A4";} }
public void Show()
{
Console.WriteLine("我是A4Paper");
}
}
四、C#中的接口和Java中的接口区别
①Java中接口通过extends来继承父接口,类通过implements实现接口;C#中通过冒号来实现这两个功能。
②Java接口中的成员变量都是常量,默认public static final修饰;C#接口中不允许存在成员变量,但是可以有属性。
③Java接口中属性和方法都可以使用public显示修饰;C#接口中不能显示使用public修饰。
④Java接口中可以定义静态常量和方法;C#接口中不允许包含任何静态成员。